java incorrect timezone
Asked Answered
R

11

13

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

Reactivate answered 21/1, 2010 at 2:31 Comment(3)
In the very old days I've seen a JVM thinking the "MET" timezone in OS/2 was not Middle European Timezone but Middle Eastern Timezone. Took me a while to figure out why all dates were 3.5 hours off.Dogy
@ThorbjørnRavnAndersen That is because the 2-4 letter abbreviation such as EST or IST are not true time zones, not standardized, and not even unique(!). Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland.Claim
@BasilBourque I think OS/2 went away before that came into being. As the initial proposal was from 1993 (mm.icann.org/pipermail/tz/1993-October/009233.html) and Warp which I used came out in 96 that sounds likely.Dogy
L
15

Ensure you set the timezone for the JVM when starting the application:

-Duser.timezone="Australia/Sydney"
Linter answered 21/1, 2010 at 2:35 Comment(2)
Was hoping for a proper solution, but ended up going with this workaround.Reactivate
-Duser.timezone="UTC"Patricide
Z
7

You should update your JRE/SDK, but TZUpdater may be sufficient.

Zest answered 21/1, 2010 at 4:40 Comment(0)
J
6

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.

Jerold answered 30/6, 2010 at 12:2 Comment(0)
B
2

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));
    }
}
Bluepencil answered 21/1, 2010 at 2:59 Comment(5)
Thanks guys, I am wondering however why I should have to manually specify the time zone. Shouldn't it be the same as the OS?Reactivate
BTW, the above code returns the correct locale, but incorrect time zone.Reactivate
It should be. You can try to update Java to the newest version, in case there's a bug.Bluepencil
Sometimes deployers don't have control over the OS settings, (me for instance). So setting it programmatically is preferred.Nuncio
@balent No, incorrect: Neither the time zone nor locale need match that of the host OS. Most JVMs default on launch to that of the host OS, but may be overridden by flags sent to the launching JVM or by any Java code calling setDefault during(!) runtime.Claim
E
2

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.
Elaelaborate answered 4/3, 2011 at 17:10 Comment(1)
We had the same issue with Java 7 after upgrading to Windows Server 2008. Changing the timezone of the system and then restoring it fixed the issue for us.Guildsman
L
1

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.

Lulululuabourg answered 5/2, 2015 at 19:9 Comment(0)
N
0

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...

Nix answered 5/1, 2012 at 5:44 Comment(0)
C
0

tl;dr

A Java programmer should never rely on the JVM’s current default time zone.

  • Always specify a proper time zone name in the format of Continent/Region, such as Africa/Casablanca.
  • Always confirm the desired/expected zone with the user, when important.

Proper time zone names

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. 

Specify time zone

Never rely on the JVM’s current default time zone. That default value can change.

  • As the other Answers explain, most JVMs by default use the host OS’ default time zone in play when the JVM launched.
  • Or the script launching the JVM may pass a flag to specify a default time zone at launch.
  • And during runtime(!) the JVM‘s current default time zone can be set by any code in any thread of any app within the JVM calling 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.)
  • And, of course, the user or sysadmin can change their current default time zone on the host OS which is not detected by running JVMs in most implementations as far as I know.

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.


Locale

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.


About java.time

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.

Claim answered 26/12, 2018 at 22:31 Comment(0)
E
0

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.

Eucalyptol answered 6/11, 2020 at 15:6 Comment(0)
P
0

I solved that error adding this to my DB URL:

?useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

Pushbike answered 6/8, 2021 at 20:56 Comment(0)
F
0

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.

Feoffee answered 17/7, 2024 at 8:8 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.