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?
- Java SE 8 and SE 9 and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android