使用JS Date()对象的奇怪

时间:2016-09-13 11:37:45

标签: javascript

好的,所以我正在编写一个简单的脚本,你可以在任何一年内提供它,它会吐出那一年每个月的天数。我的功能看起来像这样:

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;
}

就我所知,应该是一种享受,但最奇怪的事情发生在八月左右。这是控制台日志:

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]

正如你所看到的那样9月被读了两次,即使i计数明确表示8月(注意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,那么是什么给出了?

非常感谢任何帮助。干杯

1 个答案:

答案 0 :(得分:2)

逐步执行代码,看看会发生什么:

  • 初始设置,日期= 2016年9月13日
  • 输入循环
  • 将月份设为1,日期= 13/2月/ 2016
  • 将日期设为0,日期= 0/2月/ 2016 = 31/1月/ 2016
  • 记录详细信息

  • 循环的第二次迭代:

  • 将月份设为2,日期= 31 / Mar / 2016
  • 将日期设为0,日期= 0 / Mar / 2016 = 29 / Feb / 2016
  • 记录详细信息

这项工作正常,直到8月。

  • 将月份设置为8,日期= 30 / Aug / 2016
  • 将日期设为0,日期= 0/8月/ 2016 = 31 / Jul / 2016
  • 记录详细信息

  • 将月份设为9,日期= 2016年9月31日= 2016年10月1日!!!

  • 将日期设为0,日期= 0 / Oct / 2016 = 30 / Sep / 2016
  • 记录详细信息 - “八月”记录为有30天

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