Reputation: 1107
I have an instance of Java which seems to be using a completely incorrect time zone. Instead of using the Australia/Sydney time zone which Windows is using, it is using the America/Caracas time zone.
I checked the Windows time through the system clock firstly, then checked HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/
and ControlSet001
, ControlSet002
. All are set to a Sydney time zone.
Does anybody know if this is a bug in Java, or if it is referring to a time set elsewhere?
Java version is 1.6.0_06
Upvotes: 14
Views: 29297
Reputation: 2990
For anybody stumbling here not on Windows but on Linux, I found an easy fix:
The timezone is usually determined from /etc/timezone
or /etc/localtime
.
In my case I used timedatectl set-timezone
which updates /etc/localtime
, but /etc/timezone
still contained an old value.
Deleting the latter fixed the timezone value in Java for me.
Upvotes: 2
Reputation: 106
I solved that error adding this to my DB URL:
?useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Upvotes: 0
Reputation: 1562
In case time zones seem completely gone, at least in my case that Java 5 was used on a legacy system, make sure that the proper file exists in %JAVA_HOME%\jre\lib\zi folder. For instance, me, I couldn't make Europe/Athens work for the life of me. It turns out that the file %JAVA_HOME%\jre\lib\zi\Europe\Athens was missing (those directories that refer to continents were completely empty in the JDK I was using..) - did a comparison with a freshly downloaded JDK 1.5.0_22 from Oracle.
Upvotes: 0
Reputation: 338181
A Java programmer should never rely on the JVM’s current default time zone.
Continent/Region
, such as Africa/Casablanca
.Specify a proper time zone name in the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 2-4 letter abbreviation such as CST
, EST
or IST
as they are not true time zones, not standardized, and not even unique(!). For example, if you use IST
for Ireland Standard Time, you might instead get India Standard Time with surprising results.
ZoneId z = ZoneId.of( "America/Montreal" ) ; // Or "Pacific/Auckland", "Africa/Tunis", etc.
Never rely on the JVM’s current default time zone. That default value can change.
TimeZone.setDefault
. (By the way, TimeZone
is obsoleted by ZoneId
& ZoneOffset
, except for that setter method which should never be called except in the most extreme situation.) So, for all those reasons, the JVM’s current default time zone is completely out of the hands of the programmer, and even worse, can change dynamically at runtime. Therefore, using current default is not reliable.
Use the JVM’s current default time zone for only the most casual of purposes. For anything that matters, you simply must confirm the intended zone with the user. This is an inconvenient truth often resisted by programmers, but true nonetheless.
Tip: Ditto for Locale
. The JVM’s current default locale may or may not match that of the host OS, can change at any moment, and is therefore unreliable. Always confirm the desired/expected Locale
with the user.
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, SimpleDateFormat
, and java.util.TimeZone
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
Upvotes: 0
Reputation: 20059
I had the very same problem recently, apparently this is caused by an ambiguity how Windows represents its timezone settings in the registry and Java failing to interpret it correctly.
More details can be found in this article, which also describes "cures" for the affected machine:
- Changing date/time manually and then changing back to original correct time.
- Changing timezone and then back to original one.
- Requesting automatic time update from time server.
Upvotes: 2
Reputation: 391
There is a history of such problems that come and go, and no reasonable solution. See more here: Java incorrect time zone bug on Windows
Edit: Answering Tom and francis: In brief, Java runtime has hard time doing the job of correctly finding out the current time zone on the computer.
Windows registry information on the time zones has been unreliable, and the same for native windows API which relies on msvcrt.dll and various msvcrxx.dll . There is also Managed (.NET) API which requires installing a certain version of .NET Framework which contradicts portability of Java.
Thus, developers of Java runtime have hard time with the current time zone on Windows, and this may continue until Microsoft has some reason to cooperate.
If you want your Java application work correctly in any time zone, give users a possibility to correct the time zone via GUI.
Upvotes: 1
Reputation: 205765
You should update your JRE/SDK, but TZUpdater may be sufficient.
Upvotes: 7
Reputation: 2272
I had the same error, while I was setting my timezone to Malay Peninsula Standard Time, the JVM gave me Venezuela Time timezone.
The following fix works for me:
In the registry editor, edit your timezone to another timezone (I was trying to put another text like "Singapore Time". You can find the registry here:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/TimeZoneInformation
And then, I reset it back to my desired timezone using Control Panel, Date and Time setting. When I check back to the registry editor, I can see it is reverted to Malay Peninsula Standard Time. And my JVM reads it correctly now...
Upvotes: 0
Reputation: 1019
Check information on the following link:
http://techtavern.wordpress.com/2010/04/15/java-and-incorrect-timezone-on-windows-xp/
It shows, that there is a bug in JVM, causing reading incorrect default timezone from windows registry. There is no bug fix yet.
Upvotes: 6
Reputation: 1462
Try in your app to get default timezone, or set timezone manually (commented line).
Little example of mine:
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Locale locale = Locale.getDefault();
TimeZone localTimeZone = TimeZone.getDefault();
//TimeZone localTimeZone = TimeZone.getTimeZone("Australia/Sydney");
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);
dateFormat.setTimeZone(localTimeZone);
Date rightNow = new Date();
System.out.println(locale.toString() + ": " + dateFormat.format(rightNow));
}
}
Upvotes: 2
Reputation: 12342
Ensure you set the timezone for the JVM when starting the application:
-Duser.timezone="Australia/Sydney"
Upvotes: 15