记一次获取上月date的bug

博客讲述了在获取上月日期时遇到的bug,问题在于当本月有31号而上月最后一天为30号时,代码会错误地跳到当前月。解决方案是先将日期设为1再减去月份。同时提到在MySQL和Oracle数据库中使用内置函数减月是安全的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求描述

根据当前日期获取上个月的date实例,应用场景是日期条件是默认为上个月,格式为yyyyMM的形式。

问题代码

 var date=new Date();
 // 设置月份为上当前月份减1
 date.setMonth(date.getMonth()-1);

bug描述

上面的代码,在大多数情况下都是没有问题的,但是其中的bug就是,我们每个自然月的天数可能为28,29,30,31不等,假设,这个月有31号,而上个月最后一天为30号,那么,在这个月31号这天,上述代码就会变成当前月了,因为上个月并不存在31号,所以月份会自增。

问题修复

问题找到了,那么解决方式也非常简单,那就是先设置日为1,然后再设置月份即可,如下所示:

 var date=new Date();
 // 先设置日期为当前月份的第一天
 date.setDate(1);
// 然后再设置月份为上当前月份减1
date.setMonth(date.getMonth()-1);

Java版本代码可以为:

 Calendar calendar = Calendar.getInstance();
  // 设置为当前月的首日
  calendar.set(Calendar.DAY_OF_MONTH, 1);
  // 设置月份为上月
  calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);

注:如果是MySQL和Oracle数据库(其他数据库未测),使用其内置的函数来减月,是不会有问题的,他们在判断日出现溢出的时候会强制将日转换为该月的最后一日。
MySQL实例:

   select DATE_ADD(now(),INTERVAL -1 month); 

Oracle示例:

  select to_char(add_months(sysdate,-1),'yyyyMMdd') from dual;

后记

看似一个简单的代码,如果稍微不仔细就会出现bug,所以在编写代码的时候要考虑一下各种因素,尽量避免类似的bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值