什么是最好的方式来确定一个月的天数与JavaScript?

我一直在使用这个function,但我想知道什么是最有效和准确的方式来获取它。

function daysInMonth(iMonth, iYear) { return 32 - new Date(iYear, iMonth, 32).getDate(); } 
 function daysInMonth(month, year) { return new Date(year, month, 0).getDate(); } console.log(daysInMonth(2, 1999)); // February in a non-leap year console.log(daysInMonth(2, 2000)); // February in a leap year 

如果你经常调用这个函数,为了获得更好的性能,caching这个值可能是有用的。

这里是FlySwat的答案的caching版本:

 var daysInMonth = (function() { var cache = {}; return function(month, year) { var entry = year + '-' + month; if (cache[entry]) return cache[entry]; return cache[entry] = new Date(year, month, 0).getDate(); } })(); 

一些答案(还有其他问题)有闰年问题或使用date对象。 尽pipejavascript的Date object覆盖了1970年1月1日左右大约285616年(100,000,000天),但是我却厌倦了不同浏览器(最值得注意的是0到99年)的各种意想不到的date不一致 。 我也很好奇如何计算它。

所以我写了一个简单的,最重要的algorithm来计算正确的 ( 普雷格里公式 /天文/ ISO 8601:2004(第4.3.2.1条),所以第0存在,是一个闰年, 支持负数年份 )给定的月份和年份。
它使用短路位掩码模闰年algorithm (对js稍作修改)和普通的8月份algorithm。

请注意,在AD/BC记法中,0年/公元BC不存在:相反, 1 BC是闰年!
如果你需要考虑公元前记数法,那么简单地减去(否则为正数)一年的第一年! (或者从1减去年份来计算进一步的年份)

 function daysInMonth(m, y){ return m===2?y&3||!(y%25)&&y&15?28:29:30+(m+(m>>3)&1); } 
 <!-- example for the snippet --> <input type="text" value="enter year" onblur=" for( var r='', i=0, y=+this.value ; 12>i++ ; r+= 'Month: ' + i + ' has ' + daysInMonth(i, y) + ' days<br>' ); this.nextSibling.innerHTML=r; " /><div></div> 

为了避免混淆,我可能会使月份string,因为它是目前1基于。

 function daysInMonth(month,year) { monthNum = new Date(Date.parse(month +" 1,"+year)).getMonth()+1 return new Date(year, monthNum, 0).getDate(); } daysInMonth('feb', 2015) //28 daysInMonth('feb', 2008) //29 

有了moment.js,你可以使用daysInMonth()方法:

 moment().daysInMonth(); // number of days in the current month moment("2012-02", "YYYY-MM").daysInMonth() // 29 moment("2012-01", "YYYY-MM").daysInMonth() // 31 

单线直接计算(无date对象):

 function daysInMonth(m, y) {//m is 1-based, feb = 2 return 31 - (--m ^ 1? m % 7 & 1: y & 3? 3: y % 25? 2: y & 15? 3: 2); } console.log(daysInMonth(2, 1999)); // February in a non-leap year console.log(daysInMonth(2, 2000)); // February in a leap year 
 function numberOfDays(iMonth, iYear) { var myDate = new Date(iYear, iMonth + 1, 1); //find the fist day of next month var newDate = new Date(myDate - 1); //find the last day return newDate.getDate(); //return # of days in this month } 

考虑闰年:

 function (year, month) { var isLeapYear = ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0); return [31, (isLeapYear ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; } 

如果您需要Date对象当前月份的天数,请考虑以下方法:

 Date.prototype.getNumberOfDaysInMonth = function(monthOffset) { if (monthOffset !== undefined) { return new Date(this.getFullYear(), this.getMonth()+monthOffset, 0).getDate(); } else { return new Date(this.getFullYear(), this.getMonth(), 0).getDate(); } } 

那么你可以像这样运行它:

 var myDate = new Date(); myDate.getNumberOfDaysInMonth(); // Returns 28, 29, 30, 31, etc. as necessary myDate.getNumberOfDaysInMonth(); // BONUS: This also tells you the number of days in past/future months! 

在一行中:

 // month is 1-12 function getDaysInMonth(year, month){ return month == 2 ? 28 + (year % 4 == 0 ? (year % 100 == 0 ? (year % 400 == 0 ? 1 : 0) : 1):0) : 31 - (month - 1) % 7 % 2; } 

也许不是最优雅的解决scheme,但容易理解和维护; 并经过了战斗testing。

 daysInMonth(month, year) { // Note: 1 <= month <= 12, and year format yyyy. var days; switch (month) { case 2: // Feb, our problem child var leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); days = leapYear ? 29 : 28; break; case 4: case 6: case 9: case 11: days = 30; break; default: days = 31; } return days; },