如果我们在当前日期加上1个月(星期五,5月31日,18:33:00,国际标准时间2013年),它将产生:
孙俊30 18:33:00 2013
如果减去1个月,就会产生:
清华5月30日18:33:00
这是一个错误还是谁能提供推理?
请查找相同的代码:
Calendar c1 = Calendar.getInstance()
System.out.println(c1.getTime());
c1.add(Calendar.MONTH, 1);
System.out.println(c1.getTime());
c1.add(Calendar.MONTH, -1);
System.out.println(c1.getTime());输出
Fri May 31 18:33:00 IST 2013
Sun Jun 30 18:33:00 IST 2013
Thu May 30 18:33:00 IST 2013发布于 2013-06-05 13:31:45
月日的变化是预期的行为,在这里有记录,如“添加规则2":http://docs.oracle.com/javase/6/docs/api/java/util/Calendar.html
add( f,delta)将增量添加到字段f中。这相当于调用集合(f,get(f) + delta),并进行了两次调整: 添加规则1.添加规则1.调用后字段f的值减去调用前的字段f值后的值为δ,对字段f中发生的任何溢出进行模块化。溢出发生在字段值超过其范围时,结果是下一个较大字段增加或减少,字段值被调整回其范围。 添加规则2。如果一个较小的字段被期望是不变的,但是它不可能等于它的先验值,因为它的最小值或最大值在字段f被改变或其他约束条件(例如时区偏移)之后发生变化,那么它的值被调整到尽可能接近它的期望值。一个较小的字段代表一个较小的时间单位。小时是一个比DAY_OF_MONTH小的字段。对于不被期望不变的较小字段,不做任何调整。日历系统确定哪些字段是不变量的。
有了这些规则,如果您添加1个月,然后加上-1个月,就没有办法保留月中的一天。
发布于 2013-06-05 13:33:09
不,这是一个特性,并有文档记录(很抱歉在这里很挑剔,但是在询问之前,您真的读过文档吗?)阅读文档中关于add()方法的add() sectione。有关部分:
如果一个较小的字段被期望是不变的,但是它不可能等于它的先验值,因为它的最小值或最大值在字段f被改变或其他约束条件(例如时区偏移)之后发生变化,那么它的值被调整到尽可能接近它的期望值。 示例:假设最初设置为1999年8月31日的GregorianCalendar。调用add(Calendar.MONTH,13)将日历设置为2000年9月30日。Add规则1将月份字段设置为9月份,因为添加到8月的13个月将为下一年的9月。由于DAY_OF_MONTH不能在9月份的GregorianCalendar中达到31,所以添加规则2将DAY_OF_MONTH设置为30,这是最接近的值。虽然DAY_OF_WEEK是一个较小的字段,但它不受规则2的调整,因为当GregorianCalendar中的月份发生变化时,它将发生变化。
发布于 2013-06-05 13:32:59
这是正确的,因为它是设计。
如果你从5月31日起加一个月,你就会得到6月30日(这个月的最后一天)。
从6月30日起减去一个月,你就可以得到5月31日(提前一个月)。
计算是在您有时间使用getTime()时完成的。所以我在这里没有看到任何窃听器。
https://stackoverflow.com/questions/16941220
复制相似问题