乐趣区

JS-在获取当前月的最后一天遇到的坑

想阅读更多优质文章请猛戳 GitHub 博客, 一年百来篇优质文章等着你!

为了更好的讲这节的内容,提示一个 JS 处理日期的小技巧,想获取上个月最后一天,只需要设置 SetDate 参数为 0 即可。

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

接着正文开始:

使用 JS 获取当前月的最后一天,咱们通常的思路先获取下个月的第一天,然后在减去一天,就是当前月的最后一天,所以自然会用到下面的代码:

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 号,所以咱们写的代码是有 bug 的。

这又是怎么肥事?

咱们可以列出月份:

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

咱们通过 month + 1,在 JS 中会理解成:

当前日期 + 当月的天数

所以上例中的 date.setMonth(date.getMonth() + 1) 等价于 1 月 31 号 + 31 天,根据上面的列表,就可以看到结果是 3 月 3 号

所以不要认为 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    

交流

干货系列文章汇总如下,觉得不错点个 Star,欢迎 加群 互相学习。

https://github.com/qq44924588…

我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复 福利,即可看到福利,你懂的。

退出移动版