9 Time Zone Settings in the JRE

This chapter describes some issues that can arise with time zone settings with the Java Runtime Environment (JRE) on the Windows operating system. It further describes troubleshooting techniques and workarounds to solve these issues.

This chapter contains the following sections:

Native Time Zone Information and the JRE

The Java Runtime Environment (JRE) reads the native time zone information to determine your default time zone.

For example, on Windows, the JRE queries the registry to determine the default time zone.

However, the JRE also maintains its own time zone database. This provides cross-platform support because the different operating system APIs are not sufficient to support the Java APIs. The Java time zone database supports time zone IDs and determines daylight saving time rules for all the time zones that the JRE supports. The tzupdater tool is available for download from the Java SE Download Page.

Modifications to the JRE for each specific operating system are necessary so that the operating system can deliver the system time to the JRE. Then, if a Java application requests the system date by calling date and time related constructors, the system time is returned.

Examples of such constructors are:

  • java.util.Date()
  • java.util.GregorianCalendar()

Constructors related to date and time include:

  • System.currentTimeMillis()
  • System.nanoTime()

Operating system-specific patches might be required to ensure that the correct system time is delivered to the JRE.

The following sections describe troubleshooting techniques for time zone settings.

Determine the Time Zone Data Version in Use

The time zone database version that ships in any Java runtime from Oracle is documented in the release notes. However, the actual version can be different from the version mentioned there if the Java runtime was patched using the Java time zone updater tool called tzupdater.

To determine the current time zone data version of your Java runtime using the tzupdater tool, run the tool with the -V option as shown in the following example:

java -jar tzupdater.jar -V

Here is a typical output from running the tzupdater tool.

tzupdater version 2.2.0-b01
JRE tzdata version: tzdata2018g

You can download the tzupdater tool from this web page: Timezone Updater Tool.

Troubleshoot Problems with Java Time Zone Updater Tool

Sometimes, when you run tzupdater, it quits with the message: “There's no tzdata available for this Java runtime." The following are two examples.

$ java -jar tzupdater.jar -V 
tzupdater version 2.1.1-b01 
JRE tzdata version: tzdata2017b
There's no tzdata available for this Java runtime.

The likely cause is that you are using a Java runtime that is not from Oracle. Oracle provides a Java runtime for Linux (x64), Microsoft Windows (x64), and macOS (x64). Oracle does not provide the Java runtime for other platforms.

The output of running the java -version command does not provide enough information to determine the actual vendor of a Java runtime. However, running tzupdater in update mode with the -v option does print out the java.vendor property. The following example shows the result of running tzupdater when the environment is HP_UX from Hewlett Packard.

root@my_server:/opt/java6/bin> uname -a
HP-UX my_server B.11.23 U ia64 1114591084 unlimited-user license
root@my_server:/opt/java6/bin> ./java -version
java version "1.6.0.05"
Java(TM) SE Runtime Environment (build 1.6.0.05-jinteg_14_oct_2009_01_44-b00)
Java HotSpot(TM) Server VM (build 14.2-b01-jre1.6.0.05-rc5, mixed mode)
root@my_server:/opt/java6/bin> ./java -jar tzupdater.jar -v -l
java.home: /opt/java6/jre
java.vendor: Hewlett-Packard Co.
java.version: 1.6.0.05
JRE tzdata version: tzdata2009i
There's no tzdata available for this Java runtime.

In the previous example, java.vendor is set to “Hewlett-Packard Co." The Java runtime that you are trying to update using tzupdater is not supported by Oracle.

A possible solution is to visit the website of your Java runtime vendor and determine whether a time zone updater tool is available.

Determine the Default Time Zone on Windows

This section clarifies how the Java runtime determines the default time zone on Windows 10 and later operating systems. If the expected time zone isn't reported, then use the troubleshooting techniques provided in the following sections:

Check the Default Time Zone Java Runtime Reports

You can write a simple program to determine which time zone the JDK reports the default time zone-based on a check with the native operating system.

The Java program in the following example returns the default time zone:

public class DefaultTimeZone {
    public static void main(String[] args) {
        System.out.println(java.util.TimeZone.getDefault().getID());
    }
}

You can save the code snippet in the previous example to a file named DefaultTimeZone.java and compile it using the javac command. Then, you can run the compiled DefaultTimeZone class, as shown in the following example.

c:\tztest> javac DefaultTimeZone.java
c:\tztest> java DefaultTimeZone
Europe/Berlin

In the previous example, the default time zone is Europe/Berlin. Running the program should display your local time zone. If the output is not the expected time zone, then continue with the following troubleshooting steps.

Determine the Setting in the Control Panel

You can change or examine the system's default time zone using Windows Settings or the Windows Control Panel. For example, you can select this time zone setting in Windows 10:

(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna

The corresponding value for the Registry key TimeZoneKeyName is “W. Europe Standard Time."

Check for Automatic Daylight Saving Time Adjustment

You can check whether the automatic adjustment of daylight saving time is enabled through the graphical user interface (GUI) or through the Windows registry.

  • GUI Method: To use the Control Panel to check whether automatic adjustment of daylight saving time is enabled:

    1. Click the Windows Start button and then click Control Panel.

    2. Click Date and Time.

    3. Click the Change Time Zone button.

    4. There is a check box labeled “Automatically adjust time for Daylight Savings Time. “See if this check box is selected, and change the setting if you want.

    5. Click OK. This returns you to the Date and Time dialog box.

  • Windows Registry Method: You can run Windows Registry Editor to check whether automatic adjustment of daylight saving time is enabled.

    Note:

    It is a good practice to back up the Windows registry before reviewing or editing it. If you make a mistake, you can damage the Windows registry.

    To enable the automatic adjustment of daylight saving time from the Windows registry:

    1. Click the Windows Start button.

    2. In the Search programs and files field, enter regedit and then press Enter to open the Registry Editor.

    3. In the Registry Editor, search for the key DynamicDaylightTimeDisabled and look at the setting.

      If the registry setting is 1, then dynamic daylight time is disabled.

      If the registry setting is 0, then dynamic daylight time is enabled.

    If you prefer, you can access the Windows registry from the Windows command window.

In the following example, the registry setting is 1. With this setting, the clock is not automatically adjusted for daylight saving time.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"DynamicDaylightTimeDisabled"=dword:00000001

If you disable the DynamicDaylightTimeDisabled option, then Java returns a GMT (Greenwich Mean Time) offset and not a time zone ID that is compatible with the uniform naming convention (such as "Europe/Berlin"). For example, the offset will be expressed as GMT+01 and not "Europe/Berlin."

Set the Default Time Zone in Windows Settings

You can change or review the system's default time zone by using Windows Settings.

To set the system's default time zone from Windows Settings:

  1. Click the Windows Start button.
  2. Click Settings.
  3. Click Time & Language.
  4. From the Time zone drop-down list, select your preferred time zone.

For example, you can select this time zone in Windows 10:

(UTC)+1:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna.

The corresponding value for the Registry key TimeZoneKeyName is “W. Europe Standard Time."

Check -Duser.timezone System Property

You can explicitly set a default time zone on the command line by using the Java system property called user.timezone. This bypasses the settings in the Windows operating system and can be a workaround. For instance, this setting is useful if you want daylight saving time (DST) only for a single Java program running on the system.

The following example shows the system property -Duser.timezone. Compile the DefaultTimeTestZone.java program discussed in Check the Default Time Zone Java Runtime Reports from the Windows Command Prompt window. Run the following command:

c:\tztest> java -Duser.timezone=America/New_York DefaultTimeTestZone America/New_York

If setting a default time zone explicitly by specifying -Duser.timezone works for the DefaultTimeTestZone program, but does not work for your program, you should check whether your code overwrites the default Java time zone during runtime with a method call such as this:

TimeZone.setDefault(TimeZone zone)

Special Tool in Windows

The Windows operating system provides a tool called tzutil.exe. With this tool, you can request the current time zone ID abbreviation without manually reading the registry.

Here is an example of running tzutil.exe. The first line is the command that you enter in the Windows Command Prompt window. The second line is the system response.

tzutil /g

W. Europe Standard Time

Internal Representation of Time Zone Mappings

On Windows, the Java runtime uses a file <java-home>\lib\tzmappings to represent the mapping between Windows and Java time zones. Each line in the file has three tokens. The first token is the Windows time zone registry key called TimeZoneKeyName. See Determine the Setting in the Control Panel.

The second token is a country code or the default code 001, which is the UN M49 code meaning "World". The third token represents the Java time zone ID.

If you select the time zone called (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna in the Windows Control Panel, then the relevant lines in the file tzmappings are:

W. Europe Standard Time:AD:Europe/Andorra:
W. Europe Standard Time:AT:Europe/Vienna:
W. Europe Standard Time:CH:Europe/Zurich:
W. Europe Standard Time:DE:Europe/Berlin:
W. Europe Standard Time:GI:Europe/Gibraltar:
W. Europe Standard Time:IT:Europe/Rome:
W. Europe Standard Time:LI:Europe/Vaduz:
W. Europe Standard Time:LU:Europe/Luxembourg:
W. Europe Standard Time:MC:Europe/Monaco:
W. Europe Standard Time:MT:Europe/Malta:
W. Europe Standard Time:NL:Europe/Amsterdam:
W. Europe Standard Time:NO:Europe/Oslo:
W. Europe Standard Time:SE:Europe/Stockholm:
W. Europe Standard Time:SJ:Arctic/Longyearbyen:
W. Europe Standard Time:SM:Europe/San_Marino:
W. Europe Standard Time:VA:Europe/Vatican:
W. Europe Standard Time:001:Europe/Berlin:

In this example, the Java runtime recognizes your default time zone (token number three) based on your country. For example, if your country code is AD, then your default time zone is "Europe/Andorra".

If there is no appropriate mapping entry in the tzmappings file, then it is possible that Microsoft introduced a new time zone in a Windows update and that the new time zone is not available to the Java runtime. In this situation, you can file a bug report, and request a new entry in the tzmappings file from Oracle Java bugs website.

A similar disconnect between the operating system and the Java runtime is possible if you ran the tool tzedit.exe. This tool is provided by Microsoft, and allows users to add new time zones. The Java runtime is unlikely to have a time zone introduced into the system by this tool. Again, the solution is to file a bug to request that a new entry be added to the tzmappings file.