JVM Timezone is off by one hour
Using Java 6 update 30 on a Windows XP machine. Updating Java or Windows is not an option.
I need a way to change the internal Java clock back one hour to match the system time. The machine is in Russia and Windows system time is correct, but the Java time is off by one hour, probably due to DST.
I have tried changing JVM parameters as well as modifying the deployment.properties file (to change the timezone), adding a variable to the environment/system variables path also did not work, and attempted the timezone updater tool provided by Oracle. The first three do not change any parameters and the updater tool crashes, and says "Cannot find JRE/JDK files".
Is there any other way to permanently/properly change the time that Java is using.
example: Current Time : 7:20:17 PM TimeZone : sun.util.calendar.ZoneInfo [id="Europe/Moscow", offset=14400000, dstSavings=0, useDaylight=false, transitions=78, LastRule=null]
Required Time : 6:20:17 PM TimeZone : sun.util.calendar.ZoneInfo [id="Europe/Moscow", offset=14400000, dstSavings=0, useDaylight=false, transitions=78, LastRule=null]
As your first two options - upgrade the JVM and use tzupdater - are not possible, you will have to use a workaround. You can set the default timezone for the JVM using the user.timezone
property. You will need to set the timezone to a zone one hour away from the actual timezone to compensate for the 2014 changes.
Russian timezones available are
Europe/Kaliningrad
Europe/Moscow
Europe/Samara
Europe/Volgograd
Asia/Yekaterinburg
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Krasnoyarsk
Asia/Irkutsk
Asia/Yakutsk
Asia/Sakhalin
Asia/Vladivostok
Asia/Anadyr
Asia/Kamchatka
Asia/Magadan
This problem arose when attempting to get the current time from Glassfish Java Server and recieving an incorrect time stamp. In order to change the time zone it was necessary to find the domain.xml file and add a new time zone.
tl;dr
ZonedDateTime.now(
ZoneId.of( "Europe/Moscow" )
)
The Times They Are A-Changin'
Java 6 Update 30 shipped with Olson time zone data version 2011l, according to the Update Release Notes. FYI, the Olson database is now known as the 'tz database' or 'tzdata'.
Russia has experienced multiple changes to its time zones definitions since then. This makes puts your Java installation out-of-date. So you must either update the time zone database or use an alternative.
You said you tried but failed to update the time zone data.
ThreeTen-Backport project
An alternative would be the back-port of much of the technology from the java.time classes that now supplant the troublesome old date-time classes such as Date
and Calendar
. Those old classes are now legacy and should be avoided. The back-port is found in the ThreeTen-Backport project, and carries its own copy of tzdb
. You can add this library to your project, and replace it as needed with future updates to the tzdata. See the documentation to update tzdb. By the way, the "ThreeTen" refers to JSR 310.
So for the purpose of your Java code, you do not care if the host operating system's own time zone data is out-of-date, as we are not using that. Ditto for the JVM's own time zone data, we are not using that. By using only the ThreeTen-Backport classes, we use the time zone data shipped as part of that library. And we can easily keep that time zone data fresh.
Instant
The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now();
instant.toString(): 2017-01-16T07:43:24.130Z
ZonedDateTime
Apply a ZoneId
to get a ZonedDateTime
object representing the wall-clock time of a particular region.
ZoneId z = ZoneId.of( "Europe/Moscow" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString(): 2017-01-16T10:43:24.130+03:00[Europe/Moscow]
As a shortcut, you may skip dealing with the Instant
, and call ZonedDateTime.now( z )
.
See live code in IdeOne.com.
Specify time zone
Question: … Is there any other way to permanently/properly change the time that Java is using
Always pass a specific ZoneId
rather than omit any optional time zone argument. When omitted, you are implicitly relying on the JVM's current default time zone. That default can be changed at any moment by any code in any thread of any app within the JVM. So I strongly recommend you always specify your desired/expected time zone explicitly.
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
.
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.
Where to obtain the java.time classes?
上一篇: 用JavaScript比较两个日期
下一篇: JVM时区已关闭一个小时