为何两段JavaScript获取月末日期代码运行结果不同?
两段获取指定年月月末日期的JavaScript代码运行差异解析
第一段(正确运行的代码)
let getLastDayOfMonth = function(year, month) { let date = new Date(); date.setFullYear(year, month, 28); while (date.getMonth() === month){ date.setDate(date.getDate() + 1); } date.setDate(date.getDate() - 1); return date.getDate(); }; alert(getLastDayOfMonth(2012, 1)); // 29
第二段(运行异常的代码)
let getLastDayOfMonth = function(year, month) { let date = new Date(); date.setFullYear(year); date.setMonth(month); date.setDate(28); while (date.getMonth() === month){ date.setDate(date.getDate() + 1); } date.setDate(date.getDate() - 1); return date.getDate(); }; alert(getLastDayOfMonth(2012, 1)); // 结果不正确
问题
为何第一段代码调用getLastDayOfMonth(2012, 1)时能正确返回29,而第二段代码传入月份参数1时,日期会跳至3月,无法获取2月的月末日期?
原因解析
核心问题出在日期设置的顺序和setMonth方法的隐式调整行为:
第一段代码的逻辑:
调用date.setFullYear(year, month, 28)时,一次性完成年、月、日的设置,直接将日期定位到year年month月28日。后续通过循环递增日期,直到月份发生变化,再回退一天得到月末日期,整个过程不会出现跨月的意外调整。第二段代码的问题:
假设当前系统日期的日份大于28(比如当前是31号),执行步骤会出现异常:- 先调用
date.setFullYear(year):只修改年份,月份和日期保留当前系统的原始值。 - 接着调用
date.setMonth(month):如果当前日期是31号,而目标月份(2月)没有31号,JavaScript会自动将日期调整为下一个月的对应天数——比如2012年2月没有31号,就会变成2012年3月2号。 - 此时再调用
date.setDate(28):日期会被设置为3月28号,后续循环判断的是月份是否等于1(2月),但此时月份已经是2(3月),循环直接跳过,最后回退一天得到3月27号,自然返回错误结果。
- 先调用
简言之,第二段代码分步设置日期时,中间的setMonth可能因为当前日期的日份过大,触发自动跨月调整,导致后续的日期设置完全偏离了目标月份。
内容的提问来源于stack exchange,提问作者Vladislav Laykov
相关产品推荐
相关产品推荐

