需求描述
根据当前日期获取上个月的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。