JS获取当月最后一天常见Bug与修正方案

作者:小括号时间:2026-10-23 10:35:05浏览:255

本文分析JavaScript中通过下月首日减一天获取当月最后一天的常见逻辑缺陷。当日期为31号时,setMonth操作会导致日期溢出并自动进位,造成结果错误。通过先将日期重置为28号可避免此问题,确保获取准确的月末日期。

JavaScript日期处理技巧与常见陷阱

在深入讨论具体实现前,先分享一个JavaScript处理日期的实用技巧:若需获取上个月最后一天,只需将Date对象的日期参数设置为0即可实现。


var endDate = new Date();
//上个月最后一天
endDate.setDate(0);

接下来进入正题。

获取当月最后一天的常规逻辑

通常思路中,获取当前月最后一天的方法是:先获取下个月的第一天,再减去一天。基于此逻辑,常见的代码实现如下。


var date= new Date();
date.setMonth(date.getMonth() + 1);
//日期设置为0号, 0表示1号的前一天
let lastDay = date.setDate(0);
console.log('最后一天:' + new Date(lastDay).toLocaleString())

本文撰写日期为2019.08.21,因此控制台打印结果如下。

最后一天:2019/8/31 下午4:10:43

算法缺陷分析与原因解释

该算法是否存在潜在Bug尚不确定,为还原现场,我们从2019.01.31开始逐一测试。


var date= new Date(2019, 0, 31); //0 表示1月
date.setMonth(date.getMonth() + 1);
// 日期设置为0号, 0表示1号的前一天
let lastDay = date.setDate(0);
console.log('最后一天:' + new Date(lastDay).toLocaleString())

打印结果:

最后一天:2019/2/28 上午12:00:00

观察发现,我们将1月31号向后推一个月再向前减一天,理论上应得到1月31号,但实际输出为2月28号,证明上述代码存在逻辑缺陷。

这是为何?

我们可以列出月份天数分布:

1月 1 ....... 28 29 30 31 2月 1 ....... 28 3月 1 ....... 28 29 30 31

在JavaScript中,month + 1会被解析为:

当前日期数值 + 当月总天数

因此,示例中的date.setMonth(date.getMonth() + 1)等价于1月31号 + 31天。根据上述月份列表,计算结果即为3月3号。

JavaScript日期处理技巧与常见陷阱

切勿误以为month + 1仅表示月份加1,其实际含义是当前日期数值加上当月天数。

修正方案与完整代码实现

如何确保不会多跳一个月?

只要保证month + 1执行前日期不超过28号即可。具体如何实现?

推算过程如下:

  • 31号 + 31 会超
  • 30号 + 31 会超
  • 29号 + 31 会超
  • 28号 + 31 还是 28 号 刚好

关键在于将31回拨至28,因此只需额外添加以下代码:


date.setDate(28)

完整代码:


var date= new Date(2019, 0, 31); //0 表示1月
date.setDate(28)
date.setMonth(date.getMonth() + 1);
// 日期设置为0号, 0表示1号的前一天
let lastDay = date.setDate(0);
console.log('最后一天:' + new Date(lastDay).toLocaleString()) 

运行结果:

最后一天:2019/1/31 上午12:00:00

代码部署后可能存在的BUG无法实时知晓,事后为解决这些BUG,花费了大量时间进行log调试。此处顺便推荐一款好用的BUG监控工具Fundebug。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章