我们有一个简单的实用程序应用程序,它可以读取JRE中使用的所有时区数据,并将其全部显示在一个简单的表中。我们需要使用较旧版本的JRE(6_24)来发布即将发布的产品(由于显然存在其他问题),但我们还需要在该版本中包含更新的时区更新(否则将包含在6_29中) )。我们已经打包了一个将要安装的私有JRE,因此使用TZUpdater tool将时区更新到该私有JRE不是问题 - 问题是正在阅读/验证tzdata的哪个版本(例如tzdata2010o,tzdata2011k)正在使用实用程序应用程序读取(即正在运行应用程序的JRE中使用的是哪个版本)。该应用程序当前在标题栏中显示 JRE版本,但随着时区更新,这已不再足以确定正在使用哪个时区数据版本。
我查看过TimeZone类,但它似乎没有提供这些信息 - 也许有一个系统属性可以保存这些信息? TZUpdater工具知道正在使用哪个版本,所以它必须在某个地方可用 - 我无法想象他们会在分析中确定更新工具中正在使用哪个版本...有谁知道在哪里找到这个信息?
答案 0 :(得分:8)
在我的一个JRE中,JRE_PATH\lib\zi
中有一个名为ZoneInfoMappings
的文件。在第一行显示您要查找的数据。
我将寻找一种不那么强硬的方式,如果我找到了什么就会更新答案。
更新:
似乎没有API来获取这些数据。但是,类sun.util.calendar.ZoneInfoFile
中的代码显示了如何解析它。
答案 1 :(得分:3)
在Java 8中,您可以使用ZoneRulesProvider.getVersions("UTC")
:
版本的确切含义和格式是提供商特定的。版本必须遵循词典顺序,因此返回的地图将从最早的已知规则到最新的可用规则进行排序。默认的“TZDB”组使用版本编号,其中包含年份后跟字母,例如“2009e”或“2012f”。
示例:
System.out.println(java.time.zone.ZoneRulesProvider.getVersions("UTC").lastEntry().getKey());
在我的Oracle Java 8u91中,我得到:
2016a
答案 2 :(得分:1)
这是一个在IBM和Oracle JRE中对我有用的hackish:
public static void main(String args[]) throws Exception {
File f = new File(System.getProperty("java.home") + File.separator + "lib" + File.separator + "zi" + File.separator + "ZoneInfoMappings");
if (f.exists()) {
FileInputStream fis = new FileInputStream(f);
byte[] buf = new byte[11];
try {
fis.skip(11);
fis.read(buf);
System.out.print("Olson Database version is ");
System.out.println(new String(buf));
} finally {
fis.close();
}
}
}
我的jdk1.6.0_29 jre说tzdata2012i,我的websphere7 JDK说tzdata2011g
您可以谷歌那些以查看您的JDK是否已更新,以及哪些区域具有更改的内容。
答案 3 :(得分:0)
在Windows中,使用
findstr tzdata <java-home>\lib\zi\ZoneInfoMappings
以下参考和链接对于完全理解JRE中的tzdata非常有用。
http://www.oracle.com/technetwork/java/javase/tzupdater-readme-136440.html
要确定其他平台的TZData,请参阅 https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/time-zone001.html
答案 4 :(得分:0)
赞成的解决方案有效,但除了编写和执行代码之外,还可以针对每个已安装的 JRE 询问 TZ 更新程序工具本身:
<PATH to JRE bin dir>/java -jar tzupdater.jar -V
样本输出:
tzupdater version 2.3.2-b02
JRE tzdata version: tzdata2018g
tzupdater tool would update with tzdata version: tzdata2021a