JS 中 new Date 默认为1或0的问题

最近看到了一个获取天数的写法,之前一直没用过,直接上代码

let dayLength = new Date(2017,2,0); //28

有哪位大佬知道上面为什么能得到2017年2月的总天数吗?

看了 MDN 没找到答案MDN_Date

阅读 7k
3 个回答

虽然 new Date(2017,2,0) 并不是输出 28 但是它却包含 28 这个信息,确实是一个获取某月天数的好方法。

下面来说下为什么,Date 作为构造函数,有一种用法是这样的,就是题主说的这种:

new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

重点:

month 参数,是指月份,从 0 开始,也就是说,0 表示 1月,2表示 3月。

day 参数,是指月份中的某一天,从 1 开始,也就是说 1 就是月份中的第一天,2就是第二天,0 是不在取值范围内的

然后看一下 ES 规范:http://es5.github.io/#x15.9.1.12,这一节的第七和第八条:

7.Find a value t such that YearFromTime(t) == ym and MonthFromTime(t) == mn) and DateFromTime(t) == 1; but if this is not possible (because some argument is out of range), return NaN.
8.Return Day(t) + dt − 1.

简单解释下就是,传入 year, month, day 来获取一个新的日期实例时,会先获取指定年、月的 1 号,例如 year=2017, month=4,会先获取 2017-5-1 这个日期,这是上面第七步完成的。

然后第八步,上面这个日期会加上 day 参数的整数值,然后减去 1。

看见了没有,要减去 1。你上面的例子:

new Date(2017, 2, 0)

先获取 2017-3-1 然后 加上 0 ,再减去 1,就是 2017-2-28

明白了吧。

综上,咱们可以这样来获取某年某月有多少天:

function getMonthLength(year, month) {
    return new Date(year, month, 0).getDate();
}

getMonthLength(2017, 2); //28

因为day为0的话,会自动计算上个月的最后一天,在你的例子中即计算2月的最后一天

另外有一点,月份的起点是0,所以你的例子是获取3月的第0天,即2月最后一天

用你的例子来说吧
new Date(2017,2,0) =new Date(2017,1,31)

这样getDate你就没有疑问了
跨年好像不行

new Date(2017,1,0).toString()
Tue Jan 31 2017 00:00:00 GMT+0800 (CST)
推荐问题
宣传栏