我有以下代码
Calendar calendar = Calendar.getInstance();
calendar.set(2011, 7, 29); //case 1
// calendar.set(2011, 7, 30); //case 2
// calendar.set(2011, 7, 31); //case 3
System.out.println("===After seting the date== "+calendar.getTime());
System.out.println("=================================================================");
calendar.add(Calendar.MONTH, 6);
System.out.println("===result after adding 6 months== "+calendar.getTime());
对于案例2和案例3,我也得到了相同的结果。它应该溢出到下个月并显示新的日期。但它没有发生。
答案 0 :(得分:4)
目前尚不清楚你是否正在使用“应该”来表示“这就是我想要它做的事情”,或者意味着“这就是我相信它所记录的事情”。 documentation实际上支持给出的行为:
add(f,delta)将delta添加到字段f。这相当于通过两次调整来调用set(f,get(f)+ delta):
添加规则1 。调用之后的字段f的值减去调用之前的字段f的值是delta,以模拟字段f中发生的任何溢出为模。当字段值超出其范围时发生溢出,结果,下一个更大的字段递增或递减,字段值调整回其范围。
添加规则2 。如果预期较小的字段是不变的,但由于字段f改变或其他约束(例如时区偏移改变)后其最小值或最大值发生变化,它不可能等于其先前值,则其值被调整为尽可能接近其预期值。较小的字段表示较小的时间单位。 HOUR是一个比DAY_OF_MONTH小的字段。不对不希望不变的较小字段进行调整。日历系统确定预期哪些字段不变。
此外,与set()不同,add()强制立即重新计算日历的毫秒数和所有字段。
示例:考虑最初设置为1999年8月31日的GregorianCalendar。调用add(Calendar.MONTH,13)将日历设置为2000年9月30日。添加规则1将MONTH字段设置为9月,因为将8月添加到8月给了明年九月。由于在GregorianCalendar中DAY_OF_MONTH在9月不能是31,因此添加规则2将DAY_OF_MONTH设置为30,即最接近的可能值。虽然它是一个较小的字段,但DAY_OF_WEEK不会被规则2调整,因为当GregorianCalendar中月份发生变化时,它会发生变化。
示例的第二部分正是您所面临的情况:DAY_OF_MONTH预计是不变的,但必须更改才能保持在正确的月份内,因此将其调整为最接近的可能值(29 in你的情况)。
所以看起来行为 对我来说是一致的 - 你认为它与你的不一致有哪些?
答案 1 :(得分:0)
我发现以下是使用格里高利日历实现的最简单的方法。 将月中的日期设置为下个月的最后一天,以防止它成为下个月的第一天。
尝试以下操作。
cal.set(Calendar.DAY_OF_MONTH,Math.min(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DAY_OF_MONTH)));