起因
是有这么一个功能需求,统计最近四个月的订单情况,我的想法是获取当前时间点这个月的开始的第一秒和结束的第一秒以及前三个月的开始第一秒结束第一秒这个时间段,我是通过date.setMonth来设置月份以便跳到上一个月的
Date date = Date.valueOf("2016-12-31");//当前时间
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
String month = format.format(date);
String start = month + "-01 00:00:00";
String end = month + "-31 23:59:59";
for(int i = 0; i < 3; i++) {
System.out.println("before=" + date.getMonth());
int temp = date.getMonth()-1;
date.setMonth(temp);
System.out.println("after=" + date.getMonth());
month = format.format(date);
start = month + "-01 00:00:00";
end = month + "-31 23:59:59";
}
测试上线,没啥问题
但是到了2016年12月31日的时候发现统计的内容居然有两个最近一月,然后我就写了上面那段代码,发现运行的结果是这样的
before=11
after=11
before=11
after=10
before=10
after=9
也就是说有两次11月的
原因
可以看Java源代码的setMonth的注释得到原因
2016-12-31被减去了一个月如果用Date计算的话,结果是2016-11-31,但是根本没有2016-11-31这一天,所以系统把他进位了到了2016-12-1,所以造成了第一次for的时候输出两个都是11,2016-10-31也有这一种情况。
解决办法
使用Calendar来进行日期的计算
上文中的代码如果使用Calender来计算的话是这样的
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
java.util.Date date = calendar.getTime();
System.out.println(format.format(date));
for(int i = 0; i < 3; i++) {
calendar.add(Calendar.MONTH, -1);
java.util.Date temp = calendar.getTime();
System.out.println(format.format(temp));
}
涉及日期计算最好使用Calendar