夏令时更改期间的 Java Calendar.roll 和 CST

标签 java datetime timezone dst

我想知道 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/

相关文章:

java - c++动态绑定(bind)和java动态绑定(bind)有什么区别?

java - 配置 ehCache : Cache is null

sql - 如何在 SQL Server 2016 中将 ISO 8601 utc 时间转换为日期时间格式

python - pd.to_datetime 或解析日期时间不适用于我的 csv 文件(格式 : dd/mm/yyyy, hh:mm:ss)

java - 在java代码中使用EST时区时的DST

java - Java 的 NetBeans 输出做了太多事情

java - 我需要一个有效的算法和/或代码来对系统的泊松分布进行建模

java - 从当前日期开始以秒为单位获取日期时间

mysql - 无法将mysql时区设置为马德里

postgresql - 存储带有时间戳的原始时区