Duplicate :
|
FULL PRODUCT VERSION : java version "1.5.0_11" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03) Java HotSpot(TM) Client VM (build 1.5.0_11-b03, mixed mode, sharing) I believe the problem also occurs with 1.6.x. ADDITIONAL OS VERSION INFORMATION : Debian Etch Linux 2.6.18-4-686 #1 SMP Wed Feb 21 16:06:54 UTC 2007 i686 GNU/Linux A DESCRIPTION OF THE PROBLEM : Java detects the default system timezone is incorrectly under Debian Etch. I suspect the problem is not unique to Debian, as the root cause turned out to be that "/etc/localtime" is no longer a link, which is probably true for many Linux distrubutions (e.g. Ubuntu?). Details ======= The system is configured for "US/Pacific", however Java reports "SystemV/PST8PDT". The latter timezone doesn't have the correct DST settings in Java, so on top of that incorrect time is displayed. Perhaps the latter has to be fixed in a separately. My diagnosis of the problem ===================== I noticed that /etc/localtime is no longer a link in Etch. I changed it back to a symbolic link to "/usr/share/zoneinfo/US/Pacific" and Java started working correctly again. My conclusion is that Sun JVM relies on the _path and name of the zone file_ to determine the zoneID (which it then matches to its own timezone database). However since in the file is no longer a link, so they must be comparing it binary against all files under "/usr/share/zoneinfo". "/usr/share/zoneinfo/SystemV/PST8PDT" is the same file binary as ""/usr/share/zoneinfo/US/Pacific", however it is found first ! To confirm this I restored "/etc/localtime" to its non-link state, and deleted all directories under "/usr/share/zoneinfo" except "US". Voila ! Java worked again. STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Steps to reproduce ============== - Configure the system timezone to US/Pacific (using tzconfig) - In Java execute: System.out.println( java.util.TimeZone.getDefault().getDisplayName() ); It will show "SystemV/PST8PDT" - In Java execute "System.out.println( new java.util.Date() );". It currently prints the incorrect time. It will probably start printing correctly again soon, when we enter the old (pre-2007) DST period. EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - sun.util.calendar.ZoneInfo[id="US/Pacific",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=US/Pacific,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]] ACTUAL - sun.util.calendar.ZoneInfo[id="SystemV/PST8PDT",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=276,lastRule=java.util.SimpleTimeZone[id=SystemV/PST8PDT,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=3,startDay=-1,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]] REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- System.out.println( java.util.TimeZone.getDefault() ) ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : These are the possible workarounds: - Manually set the TZ environment variable. However in Debian-based distributions there is no way to set it globally, so this is not a practical solution. - Use -Duser.timezone=US/Pacific in the java command line - Change /etc/localtime to a symbolic link again