United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6456628 (tz) Default timezone is incorrectly set occasionally on Linux
JDK-6456628 : (tz) Default timezone is incorrectly set occasionally on Linux

Details
Type:
Bug
Submit Date:
2006-08-03
Status:
Closed
Updated Date:
2011-11-29
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
core-libs
OS:
linux
Sub-Component:
java.util:i18n
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0,6,6u10
Fixed Versions:

Related Reports
Backport:
Backport:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_06-b05, mixed mode)

  Bug also observed on 1.5.0_07.

ADDITIONAL OS VERSION INFORMATION :
Red Hat Enterprise Linux AS release 4 (Nahant Update 2)

Linux 2.6.9-22.20.ELsmp #1 SMP Fri Nov 18 03:04:44 EST 2005 x86_64 x86_64 x86_64 GNU/Linux


EXTRA RELEVANT SYSTEM CONFIGURATION :
Time zone is set to America/New_York, and the system time should be within the EDT period

A DESCRIPTION OF THE PROBLEM :
We have three identical Linux server and when we run the test case included below, the time reported by the machines are different.

By examining the available JVM source code, I noticed that the logic that works out the default timezone on Linux is incorrect.

The way JVM works out the default timezone is as follows:

1) Looks to environment variable TZ
This is not set in our linux box

2) JVM looks for the file /etc/sysconfig/clock and tries to find the "ZONE" entry.

However, on these host the ZONE entry does not have a double quote around the actual variable, and the JVM code is unable to recongise the entry.

3) If the ZONE entry is not found, the JVM will compare contents fo /etc/localtime with the contents of every file in /usr/share/zoneinfo recursively. When the contents matches, it returns the path and filename, referenced from /usr/share/zoneinfo

On our machine, there are three files in /usr/share/zoneinfo that matches /etc/localtime (these files are standard on RHEL4 machines):

/usr/share/zoneinfo/America/New_York
/usr/share/zoneinfo/posixrules
/usr/share/zoneinfo/EST5EDT

What happens is that depends on the way OS transverse the filesystem, the name that JVM get can be different. On the box that fail the test, the jvm actually found posixrules file first, which means that the JVM thinks the timezone is "posixrules". The JVM will then attempt to look up timezone mapping in <java.home>/jre/lib/zi directory, and it will fail the find the timezone. So it will revert to the default GMT+offset timezone id as a fail safe, which does not take into the account for daylight saving.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
We have three identical Linux server and ran the test case included below, the time reported by the machine is different.

(host 1)
bash-3.00$  date ; /opt/sunjava-1.5.0_06/jre/bin/java  simpleTest
Tue Aug  1 14:43:25 EDT 2006
Simple test Josh

 TIME ZONE :GMT-05:00
Value of milliseconds  since Epoch is 1154457805659
Value of s  in readable format is Tue Aug 01 13:43:25 GMT-05:00 2006

(host 2)
bash-3.00$ date ; /opt/sunjava-1.5.0_06/jre/bin/java  simpleTest
Tue Aug  1 14:43:36 EDT 2006
Simple test Josh

 TIME ZONE :Eastern Standard Time
Value of milliseconds  since Epoch is 1154457816528
Value of s  in readable format is Tue Aug 01 14:43:36 EDT 2006

Notice that the default timezone returned by the systems are different.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The testcase should show the same time in readable format (like host 2)
ACTUAL -
During EDT, the printed time could be different from what we are expecting

REPRODUCIBILITY :
This bug can be reproduced occasionally.

---------- BEGIN SOURCE ----------
import java.util.*;
import java.text.*;
class simpleTest
{ 
        public static void main(String args[])
        {
           System.out.println("Simple test Josh ");

           Date now = new Date();
           DateFormat df = DateFormat.getDateInstance();
                Calendar cal = Calendar.getInstance();
        System.out.println("\n TIME ZONE :"+ cal.getTimeZone().getDisplayName());
           long nowLong = now.getTime();
           String s = now.toString();
           System.out.println("Value of milliseconds  since Epoch is " + nowLong);
           System.out.println("Value of s  in readable format is " + s);

        }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
1) Set TZ to the correct timezone
2) pass -Duser.timezone with the correct timezone
3) make sure /etc/sysconfig/clock ZONE variable has quote around the value

                                    

Comments
WORK AROUND

One more workaround is to use a symlink for /etc/localtime. But it might cause some problems with Linux native code. Linux stopped using a symlink several years ago.
                                     
2006-08-03
EVALUATION

The time zone detection code for Linux was written around RedHat 6 or so. The code needs to be updated to deal with different Linux distributions.
                                     
2006-08-03
EVALUATION

According to Red Hat documentation on /etc/sysconfig/clock, the ZONE value should be a file name.

    ZONE=<filename>   ??? Indicates the timezone file under /usr/share/zoneinfo that /etc/localtime is a copy of, such as:

    ZONE="America/New York"

http://www.redhat.com/docs/manuals/linux/RHL-7.2-Manual/ref-guide/s1-boot-init-shutdown-sysconfig.html

So if the ZONE value is "America/New York", "/usr/share/zoneinfo/America/New York" should exist.

It's not clear from the documentation, but the example uses ".
                                     
2009-03-16
EVALUATION

RHES 5.3:

/etc/sysconfig/clock contains ZONE as:

ZONE="<olson_tzid>"

such as ZONE="America/Los_Angeles" (uses double quotes and '_').

Fedora 11:

/etc/sysconfig/clock contains ZONE as:

ZONE="<system-config-date-tzname>"

such as ZONE="America/Los Angeles" (uses double quotes and ' ').

Both the operating systems suggest that /etc/sysconfig/clock be used only by system-config-date. So, Java shouldn't look up /etc/sysconfig/clock after all even it's very expensive to scan /usr/share/zoneinfo.

The change to ignore "posixrules" was made as a 6533916 fix.
                                     
2009-07-21
EVALUATION

The remaining work is to remove the /etc/sysconfig/clock support for RH and Fedora, and to add /etc/timezone support for Ubuntu (Debian distros).
                                     
2009-08-07



Hardware and Software, Engineered to Work Together