JavaScript 中 Date 细节问题导致的程序 Bug

该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/post/2016/09/05/js-calender-bug-with-date-carrying/

今天遇到一个 Bug,是在逢 31 号当天,日历控件(同事开发的)就会出问题。 表现为凡是有 31 号的月份几乎都不显示 31 号,但是部分月份如 12 月和 7 月除外。

检查代码发现出错的位置在于

1//返回某月天数
2function getDaysBayYearAndMonth(year, month) {
3
4    var date = new Date();
5    date.setFullYear(year);
6    date.setMonth(month);
7    date.setDate(0);
8    return date.getDate();
9}

把系统时间设置为 8 月 31 号,重启浏览器,因为是当天发现的。 从这个函数体开始单步调试,依次检查,发现结果如下:

 1/**
 2 * 调用函数 getDaysBayYearAndMonth(2016, 8)
 3 */
 4function getDaysBayYearAndMonth(year, month) {
 5
 6    var date = new Date(); // 2016-08-31
 7    date.setFullYear(year); // 2016-08-31
 8    date.setMonth(month);  // 2016-10-01
 9    date.setDate(0); // 2016-09-30
10    return date.getDate(); // 30
11}

找到问题的关键所在了,因为 setMonth 修改了月份为 9 月,而 9 月没有 31 号,遂自动进位到 10 月 1 日。 然后再设置 setDate(0) 使得返回上个月最后一天,变成了 9 月 30 日。

那 12 月和 7 月为什么没有问题呢?因为 7 月的下一个月是 8 月,而 12 月的下一个月是 1 月,1 月和 8 月都是有 31 号的。

问题遂解。

comments powered by Disqus