JS Date()对象的奇怪之处

Oddities with JS Date() Object

本文关键字:对象 Date JS      更新时间:2023-09-26

好的,我正在编写一个简单的脚本,您可以输入任何年份,它将吐出该年份每个月的天数。我的函数看起来像这样:

function( year ){
    var months = [];
    var date = new Date();
    date.setFullYear( year );

    for( i = 1; i < 13; i++ ){
        date.setMonth( i );
        date.setDate( 0 );
        months[i] = date.getDate();
        console.log([date, i, date.getMonth()]);
    }
    console.log(months);
    return months;
}

据我所知,应该是一件好事,但最奇怪的事情发生在8月左右。下面是控制台日志:

VM691:10 [Sun Jan 31 2016 12:31:41 GMT+0000 (GMT), 1, 0]
VM691:10 [Mon Feb 29 2016 12:31:41 GMT+0000 (GMT), 2, 1]
VM691:10 [Thu Mar 31 2016 12:31:41 GMT+0100 (BST), 3, 2]
VM691:10 [Sat Apr 30 2016 12:31:41 GMT+0100 (BST), 4, 3]
VM691:10 [Tue May 31 2016 12:31:41 GMT+0100 (BST), 5, 4]
VM691:10 [Thu Jun 30 2016 12:31:41 GMT+0100 (BST), 6, 5]
VM691:10 [Sun Jul 31 2016 12:31:41 GMT+0100 (BST), 7, 6]
VM691:10 [Fri Sep 30 2016 12:31:41 GMT+0100 (BST), 8, 8]
VM691:10 [Fri Sep 30 2016 12:31:41 GMT+0100 (BST), 9, 8]
VM691:10 [Mon Oct 31 2016 12:31:41 GMT+0000 (GMT), 10, 9]
VM691:10 [Wed Nov 30 2016 12:31:41 GMT+0000 (GMT), 11, 10]
VM691:10 [Sat Dec 31 2016 12:31:41 GMT+0000 (GMT), 12, 11]
VM691:13 [1: 31, 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 30, 9: 30, 10: 31, 11: 30, 12: 31]

可以看到,尽管i计数清楚地表明是8月,但9月被读取了两次(注意setMonth(i)以经典顺序读取月份,即1 = 1月,但getMonth()以编程顺序0 = 1月返回它们)。因此,我做了一些研究,发现当setMonth方法显式设置为8(8月)时,控制台返回一个在8月和9月之间波动的列表:

VM757:10 [Wed Aug 31 2016 12:36:12 GMT+0100 (BST), 1, 7]
VM757:10 [Fri Sep 30 2016 12:36:12 GMT+0100 (BST), 2, 8]
VM757:10 [Wed Aug 31 2016 12:36:12 GMT+0100 (BST), 3, 7]
VM757:10 [Fri Sep 30 2016 12:36:12 GMT+0100 (BST), 4, 8]
VM757:10 [Wed Aug 31 2016 12:36:12 GMT+0100 (BST), 5, 7]
VM757:10 [Fri Sep 30 2016 12:36:12 GMT+0100 (BST), 6, 8]
VM757:10 [Wed Aug 31 2016 12:36:12 GMT+0100 (BST), 7, 7]
VM757:10 [Fri Sep 30 2016 12:36:12 GMT+0100 (BST), 8, 8]
VM757:10 [Wed Aug 31 2016 12:36:12 GMT+0100 (BST), 9, 7]
VM757:10 [Fri Sep 30 2016 12:36:12 GMT+0100 (BST), 10, 8]
VM757:10 [Wed Aug 31 2016 12:36:12 GMT+0100 (BST), 11, 7]
VM757:10 [Fri Sep 30 2016 12:36:12 GMT+0100 (BST), 12, 8]
VM757:13 [1: 31, 2: 30, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 30, 9: 31, 10: 30, 11: 31, 12: 30]

当设置为9时,它只返回9月,而在设置为7时只返回7月,那么发生了什么?

任何帮助都将非常感激。欢呼声

遍历代码,看看会发生什么:

  • 初始设置,日期= 2016年9月13日
  • 进入循环
  • 设置月为1,日期为2016年2月13日
  • 设置日期为0,日期= 0/Feb/2016 = 31/Jan/2016

  • 日志细节,

  • 循环的第二次迭代:

  • 设置月为2,日期为2016年3月31日
  • 设置日期为0,日期= 2016年3月29日

直到八月,这一切都很好。

  • 设置月为8,日期为2016年8月30日
  • 设置日期为0,日期= 2016年8月31日

  • 日志细节,

  • 设置月为9,日期= 31/Sep/2016 = 1/Oct/2016 !!

  • 设置日期为0,日期= 0/Oct/2016 = 30/Sep/2016
  • 日志详细信息-"august"被记录为有30天

要解决这个问题,在循环开始时调用setDate(1),以确保在设置月份时不会出现任何溢出问题。