TimeZone.getTimeZone()。getRawOffset()取决于什么?

时间:2018-06-13 15:53:04

标签: java timezone timezone-offset

当我在 ideone 上运行此代码时:https://ideone.com/sm2SHC我在stdout中收到10800000,当我在本地运行时,我可以看到7200000

产生此输出的代码是:

System.out.println(TimeZone.getTimeZone("Africa/Khartoum").getRawOffset());

1 个答案:

答案 0 :(得分:1)

getRawOffset方法as described in the documentation以毫秒为单位返回当前日期的原始偏移值(如果适用,不含DST)。除以3600000以达到数小时,您会看到您报告的值在IDEOne中为UTC + 3,在本地环境中为UTC + 2。

如果我们查看基础tz database条目for this time zone,我们会看到以下内容:

# Zone  NAME            GMTOFF   RULES  FORMAT  [UNTIL]
Zone    Africa/Khartoum 2:10:08  -      LMT     1931
                        2:00     Sudan  CA%sT   2000 Jan 15 12:00
                        3:00     -      EAT     2017 Nov  1
                        2:00     -      CAT

最后两个条目显示UTC + 3生效至2017年11月1日,此时喀土穆切换到UTC + 2。深入挖掘,您会发现此更改是在2017c版本中进行的,并且包含在the release announcement here中。

Java随每个JRE版本(以及通过名为TZUpdater的单独的带外进程)发布TZDB更新。我们可以update your IDEOne查看在那里运行的TZDB和JRE版本。

System.out.println(java.time.zone.ZoneRulesProvider.getVersions("UTC").keySet());
System.out.println(System.getProperty("java.version"));

// outputs [2016f] and 1.8.0_112

事实上,我们可以在Oracle's list of time zone versions in JRE中看到,2016f首次发布8u111,下一次带内发布是2016i的8u121。 The Wikipedia page on Java Updates确认Java 8更新112于2016-10-18发布。

由于喀土穆还没有转移到UTC + 2,那么旧版本的Java根本就没有这些信息。 IDEOne需要更新其JRE版本或运行TZUpdater以携带更新的信息。

可能您的本地环境是Java的更新版本,它具有2017c或更高版本的时区数据。

此外,现代Java应该不再使用java.util.TimeZone,而应该更喜欢improved java.time APIs。使用这些API,您可能不需要直接使用原始偏移值。