我想知道 Calendar.roll 是否尊重它的 javadoc 契约(Contract):
运行以下片段
final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("CST"));
cal.setTimeInMillis(1457928024812l);
System.out.println(cal.getTime());
cal.roll(Calendar.HOUR_OF_DAY, true);
System.out.println(cal.getTime());
产生以下输出:
Sun Mar 13 23:00:24 CDT 2016
Sun Mar 13 23:00:24 CDT 2016
2016 年 3 月 13 日是凌晨 2 点的夏令时更改(从 CST 到 CDT)。 roll 的 javadoc 指出 roll“添加一个时间单位”,这里没有添加任何时间单位。 这是此方法的预期行为吗?
编辑:
我将此报告为错误。有关更多信息,请访问相应 OpenJDK 票证的链接:https://bugs.openjdk.java.net/browse/JDK-8152077
最佳答案
这似乎是 roll
方法中的实际错误。不错的发现!
一些注意事项:
我不得不使用
SimpleDateFormat
来获得您显示的准确结果,因为只要调用getTime
就会得到一个Date
对象在本地时区打印。最好使用
America/Chicago
而不是CST
,但这不是造成这种情况的原因。对于任何常规日期,从第 23 小时滚动到同一天的第 0 小时。如果您只想增加一个小时,请使用
add
而不是roll
。参见 add vs roll .add
方法似乎工作正常。在春节前夕,一天只有 23 小时。
roll
方法似乎考虑了这一点,即使它没有跨越实际的转换(在这个时区接近 2:00 时发生,此时时钟跳到 3:00)。如您所示,它将小时设置为23
,比它应该设置的0
早一小时。在回退过渡的那天,一天有 25 个小时。同样,
roll
方法尝试将这一点考虑在内,将小时设置为1
而不是0
,即使它没有跨越实际转换(在这个时区接近 2:00 时再次发生,此时时钟拨回 1:00)。
我做了一个快速搜索,看看是否已经在任何地方报告过这个问题,但没有找到太多。也许你应该 report it .
我还要补充一点,您可能应该考虑使用 Joda Time对于 Java 7 或更早版本,以及 java.time
适用于 Java 8 或更新版本。
关于夏令时更改期间的 Java Calendar.roll 和 CST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35986033/