使用JavaScript确定一个月内的天数的最佳方法是什么?

Cha*_*atu 96 javascript date

我一直在使用这个功能,但我想知道什么是最有效和最准确的方法.

function daysInMonth(iMonth, iYear) {
   return 32 - new Date(iYear, iMonth, 32).getDate();
}
Run Code Online (Sandbox Code Playgroud)

Fly*_*wat 179

function daysInMonth (month, year) { // Use 1 for January, 2 for February, etc.
  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.
Run Code Online (Sandbox Code Playgroud)

第0天是上个月的最后一天.因为月构造函数是从0开始的,所以这很好用.有点黑客,但这基本上是你通过减去32来做的.

  • 这种语法让我困惑了一段时间.为了遵循JS模式,我建议实现这样的技巧:`return new Date(year,month + 1,0).getDate();` (39认同)
  • 注意我的未来自我:fguillen的'+ 1'等式给出28天,当年是2014年,月份是1(在JavaScript日期对象中,表示2月).可能想要与此至少惊讶.但FlySwat真是个好主意! (4认同)
  • 如果 `month` 是 **12** 会怎样?`Date` 构造函数不应该取一个从 **0 到 11** 的值吗? (3认同)
  • 不幸的是,在公元1000年之前的日期失败,您只能使用SetFullYear()正确设置年份.为了使它成为防弹使用新的日期(2000+(年%2000),月,0).getDate() (2认同)

dol*_*men 8

如果经常调用此函数,则缓存该值以获得更好的性能可能很有用.

这是FlySwat的缓存版本的答案:

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();
    }
})();
Run Code Online (Sandbox Code Playgroud)

  • 内部C/C++例程是否如此慢以至于需要缓存? (5认同)

Git*_*LAB 5

一些答案(也在其他问题上)有闰年问题或使用Date-object.虽然javascript Date object在1970年1月1日的两边都覆盖了大约285616年(100,000,000天),但我厌倦了不同浏览器中的各种意外日期不一致(最明显的是0到99年).我也很好奇如何计算它.

所以我写了一个简单的,最重要的,算法来计算正确的(Proleptic Gregorian/Astronomical/ISO 8601:2004(第4.3.2.1节),所以年份0存在并且是闰年,支持负年份)天数为给定的月份和年份.
它使用短路位掩码模数leapYear算法(略微修改为js)和常见的mod- 8月算法.

请注意,在AD/BC表示法中,第0年AD/BC不存在:相反年份1 BC是闰年!
如果您需要考虑BC符号,那么只需减去一年(否则为正)年值!(或者将年份减去1进一步的年度计算.)

function daysInMonth(m, y){
  return m===2?y&3||!(y%25)&&y&15?28:29:30+(m+(m>>3)&1);
}
Run Code Online (Sandbox Code Playgroud)
<!-- 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>
Run Code Online (Sandbox Code Playgroud)

注意,月份必须是1个!

注意,这是一个不同的算法,然后我在我的Javascript中使用的幻数查找计算一年中的日期(1 - 366)答案,因为这里闰年的额外分支仅在2月需要.