JDK-6456628 : (tz) Default timezone is incorrectly set occasionally on Linux
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 5.0,6,6u10
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2006-08-03
  • Updated: 2011-11-29
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u18Fixed 7 b72Fixed OpenJDK6Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
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
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).
07-08-2009

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.
21-07-2009

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 ".
16-03-2009

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.
03-08-2006

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.
03-08-2006