【问题标题】:Java - find tzdata version in use regardless of JRE versionJava - 查找正在使用的 tzdata 版本,无论 JRE 版本如何
【发布时间】:2011-10-31 15:45:41
【问题描述】:

我们有一个简单的实用程序应用程序,它可以读取 JRE 中使用的所有时区数据,并将其全部显示在一个简单的表格中。我们需要为即将发布的产品版本使用旧版本的 JRE (6_24)(显然是由于其他问题),但我们还需要在该版本中包含较新的时区更新(否则将包含在 6_29 )。我们已经打包了一个将要安装的私有 JRE,因此使用 TZUpdater tool 将时区更新到该私有 JRE 不是问题 - 问题是读取/验证 tzdata 的哪个版本(例如 tzdata2010o, tzdata2011k) 正在使用实用程序应用程序读取(即应用程序正在运行的 JRE 中使用哪个版本)。该应用当前在标题栏中显示 JRE 版本,但随着时区更新,这已不足以确定正在使用的 时区数据 版本。 p>

我查看了TimeZone 类,但它似乎没有提供这些信息——也许有一个系统属性保存了这些信息? TZUpdater 工具知道正在使用哪个版本,因此它必须在某个地方可用 - 我无法想象他们会分析确定更新工具中正在使用哪个版本...有人知道在哪里可以找到此信息吗?

【问题讨论】:

    标签: java timezone


    【解决方案1】:

    ZoneRulesProvider.getVersions

    在 Java 8 中,您可以使用 ZoneRulesProvider.getVersions("UTC"):

    版本的确切含义和格式是特定于提供商的。版本必须遵循字典顺序,因此返回的映射将按照从最旧的已知规则到最新的可用规则的​​顺序。默认的“TZDB”组使用由年份和字母组成的版本编号,例如“2009e”或“2012f”。

    例子:

    System.out.println(
        java.time.zone.ZoneRulesProvider
                      .getVersions("UTC")
                      .lastEntry()
                      .getKey()
    );
    

    在我的 Oracle Java 8u91 中,我得到:

    2016a

    看到这个code run live at IdeOne.com

    【讨论】:

      【解决方案2】:

      在我的一个 JRE 中,JRE_PATH\lib\zi 中有一个名为 ZoneInfoMappings 的文件。在第一行,它显示了您要查找的数据。

      我将寻找一种不那么骇人听闻的方式,如果我发现了什么,我会更新答案。

      更新: 似乎没有 API 可以获取这些数据。但是,sun.util.calendar.ZoneInfoFile 类中的代码显示了如何解析它。

      【讨论】:

      • 是的,这是被 TZUpdater 替换的文件夹,我确实注意到(在发布问题后)ZoneInfoMappings 包含该行,但 Notepad++ 在第一行中显示了它周围的一些其他数据/字符让我觉得它需要一些 hackish 的东西才能得到它......所以希望有更好的方法从 JRE 得到它,或者有人可以发布代码来读取该文件/行......
      • 以此处的代码为例进行解析:docjar.com/html/api/sun/util/calendar/ZoneInfoFile.java.html
      • 如果您使用的是 Linux,您可以从命令行执行此操作:strings ZoneInfoMappings | head -2
      • 在 Java 8 中,您可以使用ZoneRulesProvider.getVersions("UTC")
      • @Andreas 请将您的评论作为单独的答案发表。重要且与其他答案不同。
      【解决方案3】:

      这是一个在 IBM 和 Oracle JRE 中都适用于我的骇人听闻的事情:

      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

      您可以通过 google 来查看您的 JDK 是否已更新,以及哪些区域有哪些 tz 更改。

      【讨论】:

        【解决方案4】:

        在 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

        【讨论】:

          【解决方案5】:

          赞成的解决方案有效,但无需编写和执行代码,还可以向 TZ Updater 工具本身询问每个已安装的 JRE:

          <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
          

          【讨论】:

            【解决方案6】:

            如果您使用的是 Azul JDK,您可以在此处找到此信息: JAVA_HOME/jre/lib/tzdb.dat

            示例(Linux):

            $ stings tzdb.dat | grep -i "America/Sao_Paulo"
            America/Sao_Paulo
            

            【讨论】:

              猜你喜欢
              • 2012-05-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-12-09
              • 1970-01-01
              • 2010-09-18
              • 1970-01-01
              相关资源
              最近更新 更多