You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何两段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号),执行步骤会出现异常:

    1. 先调用date.setFullYear(year):只修改年份,月份和日期保留当前系统的原始值。
    2. 接着调用date.setMonth(month):如果当前日期是31号,而目标月份(2月)没有31号,JavaScript会自动将日期调整为下一个月的对应天数——比如2012年2月没有31号,就会变成2012年3月2号。
    3. 此时再调用date.setDate(28):日期会被设置为3月28号,后续循环判断的是月份是否等于1(2月),但此时月份已经是2(3月),循环直接跳过,最后回退一天得到3月27号,自然返回错误结果。

简言之,第二段代码分步设置日期时,中间的setMonth可能因为当前日期的日份过大,触发自动跨月调整,导致后续的日期设置完全偏离了目标月份。

内容的提问来源于stack exchange,提问作者Vladislav Laykov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:16:21