Java Default Timezone Issue Under Fedora Redhat Linux

Written by Geoff Mottram (geoff at minaret dot biz).

Placed in the public domain on December 5, 2004 by the author.

This document is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the author be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with this document or the use or other dealings in this document.

Description
I encountered a problem with Java 1.4.2 running under Fedora Redhat Linux (Core Release 1) where Java was not detecting the correct default timezone from the operating system. It was defaulting to the US/Pacific timezone even though the Linux date command returned the correct timezone (US/Eastern in my case).

To test what the default timezone of your JVM is, compile and run the following code:

import java.util.Date;
import java.util.TimeZone;

public class TimeTest {

    public static void main(String args[]) {
	long time = System.currentTimeMillis();
	String millis = Long.toString(time);
	Date date = new Date(time);
	System.out.println("Current time in milliseconds = " + millis + " => " + date.toString());
	System.out.println("Current time zone: " + TimeZone.getDefault().getID());
    }
}

If the default timezone that Java is using does not match your system timezone (the Linux date command is one way of checking), the JVM is not successfully detecting your system timezone.

Solution
Under Linux, you can force Java to use a particular timezone by setting the TZ environment variable to an appropriate value. To set the TZ environment variable for all instances of the bash shell, create a shell script in the /etc/profile.d directory with a line similar to this:

export TZ="US/Eastern"

[Please note: All of the examples on this page use the US/Eastern timezone. Please substitute your timezone, as appropriate.]

If your system does not support the /etc/profile.d directory, add the previous line to the /etc/profile initialization script.

Under most versions of Linux, you can determine your system default timezone by checking where the symbolic link /etc/localtime points to by using the ls -l /etc/localtime command. The response will look something like this:

/etc/localtime -> /usr/share/zoneinfo/US/Eastern

The portion of the name after /usr/share/zoneinfo/ is your TZ value.

Any shell scripts that are started through /etc/init.d do not run the /etc/profile code. Therefore, any Java programs you start via /etc/init.d must have an explicit export TZ="US/Eastern" in order to work correctly.

Once you have set the TZ variable (you must log out and log back in to see the change), it will become part of your shell environment. To check that you have successfully set the value of TZ, type the following command at your shell prompt:

echo $TZ

Alternatives
You can also force the use of a particular default timezone in Java either through programming or with a Java system property. The programming alternative is the least attractive as it requires that you change your Java programs by adding a line early in the program like this:

TimeZone.setDefault(TimeZone.getTimeZone("US/Eastern"))

To set the default timezone using a system property, set the user.timezone property to your time zone. One place to do this is on command line that starts your Java interpreter using the -D startup option, like this:

java -Duser.timezone=US/Eastern CLASS_NAME

While this last technique works, be forewarned that this property is not part of the Java specification.

Technical Tips