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

IT技术 javascript date
2021-01-14 05:39:57

我一直在使用此功能,但我想知道获得它的最有效和最准确的方法是什么。

function daysInMonth(iMonth, iYear) {
   return 32 - new Date(iYear, iMonth, 32).getDate();
}
6个回答

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.

第 0 天是上个月的最后一天。因为月份构造函数是基于 0 的,所以这很好用。有点小技巧,但这基本上就是你通过减去 32 所做的。

查看更多: 当月的天数

请注意我未来的自己:当年份为 2014 且月份为 1(在 JavaScript 日期对象中,表示二月)时,带有“+ 1”的 fguillen 方程给出了 28 天。可能想用那个最少的惊讶。但是 FlySwat 的创意真是太棒了!
2021-03-14 05:39:57
不幸的是,这对于公元 1000 年之前的日期失败,您只能使用 SetFullYear() 正确设置年份。为了使其防弹使用 new Date( 2000+(year%2000), month, 0 ).getDate()
2021-03-17 05:39:57
这种语法让我困惑了一段时间。为了遵循 JS 模式,我建议您实现这样的技巧:return new Date(year, month + 1, 0).getDate();
2021-03-23 05:39:57
@NoelWalters——你是对的,有些浏览器错误地将两位数的年份转换为 20 世纪的日期(所以日期在公元 100 年之前,而不是公元 1000 年),但是你的修复并没有在这些浏览器中纠正这个问题。可靠地设置两位数年份的唯一方法是使用setFullYear : var d=new Date();d.setFullYear(year, month, date);
2021-03-28 05:39:57
如果month12呢?Date构造函数不应该取一个从0 到 11的值吗?
2021-04-11 05:39:57

一些答案(也在其他问题上)有闰年问题或使用了日期对象。尽管 javascriptDate object涵盖了 1970 年 1 月 1 日左右的大约 285616 年(100,000,000 天),但我已经厌倦了不同浏览器(最显着的是 0 到 99 年)的各种意外日期不一致我也很好奇如何计算。

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

请注意,在AD/BC符号中,公元 0 年不存在:相反,年份1 BC是闰年!
如果您需要考虑 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>

注意,月份必须以 1 为基础!

请注意,这是一种不同的算法,然后我在我的Javascript 中使用的幻数查找计算一年中的第几天 (1 - 366)答案,因为这里闰年的额外分支只需要在二月份进行。

这个答案值得更多选票!这是我看到的唯一一个不创建新 Date 对象的对象,如果多次执行此操作,这是必须的。
2021-03-18 05:39:57

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

这是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();
    }
})();
内部 C/C++ 例程是否太慢以至于需要缓存?
2021-03-21 05:39:57
@PeteAlvin 这取决于的实现Date(因此该问题没有统一的答案)以及您的代码dayInMonth使用相同值调用 的频率因此,唯一合理的答案是:分析您的代码并对其进行基准测试!
2021-04-08 05:39:57
我喜欢!但我没有使用新对象cache,而是使用localStorage.
2021-04-10 05:39:57

使用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

为了消除混淆,我可能会基于月份字符串,因为它目前是基于 0 的。

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