Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - find tzdata version in use regardless of JRE version

Tags:

java

timezone

We have a simple utility app that reads all the time zone data used in a JRE and displays it all in a simple table. We need to use an older version of the JRE (6_24) for an upcoming product release (due to other issues apparently), but we also need to include newer time zone updates in that release (that would otherwise be included in, say, 6_29). We're already packaging a private JRE that will be installed, so getting the time zone updates into that private JRE using the TZUpdater tool is not the issue - The issue is reading/verifying which version of the tzdata (e.g. tzdata2010o, tzdata2011k) is being read with the utility app (i.e. which version is being used in the JRE the app is running in). The app currently displays the JRE version in the title bar, but with the time zone updates, that's no longer sufficient to determine which time zone data version is in use.

I've looked into the TimeZone class, but it doesn't seem to provide this information - perhaps there is a system property that holds this info? The TZUpdater tool knows which version is being used, so it must be available somewhere - I can't imagine they would analytically determine which version is in use in the update tool... Anybody know where to locate this info?

like image 980
johnny Avatar asked Oct 31 '11 15:10

johnny


3 Answers

ZoneRulesProvider.getVersions

In Java 8, you can use ZoneRulesProvider.getVersions("UTC"):

The exact meaning and format of the version is provider specific. The version must follow lexicographical order, thus the returned map will be order from the oldest known rules to the newest available rules. The default 'TZDB' group uses version numbering consisting of the year followed by a letter, such as '2009e' or '2012f'.

Example:

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

In my Oracle Java 8u91, I get:

2016a

See this code run live at IdeOne.com.

like image 186
Andreas Avatar answered Nov 13 '22 23:11

Andreas


In one of my JREs, there's a file in JRE_PATH\lib\zi named ZoneInfoMappings. In the first line it displays the data you are looking for.

I'm going to search for a less hackish way, will update answer if I find something.

UPDATE: Seems that there's no API to get this data. However, the code in the class sun.util.calendar.ZoneInfoFile shows how to parse it.

like image 9
Mister Smith Avatar answered Nov 13 '22 22:11

Mister Smith


Here's a hackish thing that worked for me in both IBM and Oracle JREs:

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();
        }
    }       
}

My jdk1.6.0_29 jre says tzdata2012i, and my websphere7 JDK says tzdata2011g

You can google those to see whether your JDK is updated, and which zones have what tz changes.

like image 1
Jim P Avatar answered Nov 13 '22 23:11

Jim P