1

如果我们在当前日期(2013 年 5 月 31 日星期五 18:33:00 IST 2013)添加 1 个月,则会产生:

2013 年 6 月 30 日星期日 18:33:00 IST

如果我们减去 1 个月,它会产生:

2013 年 5 月 30 日星期四 18:33:00 IST

这是一个错误还是任何人都可以提供推理?

请找到相同的代码:

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
4

4 回答 4

6

更改月份是预期的行为,此处记录为“添加规则 2”:http ://docs.oracle.com/javase/6/docs/api/java/util/Calendar.html

add(f, delta)将 delta 添加到字段 f。这相当于调用 set(f, get(f) + delta) 并进行两次调整:

添加规则 1。调用后字段 f 的值减去调用前字段 f 的值是 delta,以字段 f 中发生的任何溢出为模。当字段值超出其范围时会发生溢出,因此,下一个较大的字段会递增或递减,并且字段值会调整回其范围内。

添加规则 2。如果期望较小的字段是不变的,但由于字段 f 更改后其最小值或最大值的变化或其他约束,例如时区偏移量变化,它不可能等于它的先前值,那么它的值调整为尽可能接近其预期值。较小的字段表示较小的时间单位。HOUR 是比 DAY_OF_MONTH 小的字段。不对预期不会保持不变的较小字段进行任何调整。日历系统确定哪些字段预计是不变的。

有了这些规则,如果您添加 1 个月,然后添加 -1 个月,则无法保留月份中的某天。

于 2013-06-05T13:31:45.610 回答
1

不,它是一项功能并且已记录在案(抱歉在这里很挑剔,但您在询问之前是否真的阅读过文档?)。阅读Field Manipulation文档中有关该方法的部分。add()相关部分:

如果期望较小的字段是不变的,但由于字段 f 更改后其最小值或最大值的变化或其他约束,例如时区偏移量变化,它不可能等于它的先前值,那么它的值调整为尽可能接近其预期值。

示例:考虑最初设置为 1999 年 8 月 31 日的 GregorianCalendar。调用 add(Calendar.MONTH, 13) 将日历设置为 2000 年 9 月 30 日。添加规则 1 将 MONTH 字段设置为九月,因为在八月添加 13 个月会给出九月下一年。由于 DAY_OF_MONTH 在 GregorianCalendar 中不能为 9 月的 31,因此添加规则 2 将 DAY_OF_MONTH 设置为 30,这是最接近的可能值。虽然它是一个较小的字段,但 DAY_OF_WEEK 不会被规则 2 调整,因为它预计会随着 GregorianCalendar 中月份的变化而变化。

于 2013-06-05T13:33:09.027 回答
0

这是正确的,因为它是设计的。

当您从 5 月 31 日开始添加一个月时,您将得到 6 月 30 日(该月的最后一天)。

当您从 6 月 30 日减去一个月时,您将得到 5 月 31 日(提前一个月)。

当你得到时间时,计算就完成了getTime()。因此我在这里看不到任何错误。

于 2013-06-05T13:32:59.957 回答
0
于 2017-03-23T22:24:10.217 回答