Learn about ZonedDateTime and OffsetDateTime classes in Java, and what are the main differences between both classes in depth.
1. Understanding Zone Id and Zone Offsets
Before jumping to the internals of the classes, let’s make sure we understand the difference between the zone identifier and zone offsets.
Most programming languages measure the time from a specific point in time (called the epoch). For example, the Java Date represents a
long value for the number of milliseconds since 00:00 (midnight) on January 1, 1970 in UTC (or GMT).
Such values are time-zone-independent since, at any given moment, it is identical in UTC everywhere on Earth. But this time value can be transformed into any particular time zone offset, for display and processing purposes.
- A zone offset is a difference in hours and minutes between a particular time zone and UTC. For example, the value -08:00 represents a given time in a time zone 8 hours behind UTC.
- A zone identifier (timezone) is an identifier for a specific location or region which translates into a combination of rules for calculating the zone offset. A timezone can have more than one offset tied to it during the year.
For example, Pacific Time does not have a fixed offset from UTC; instead, the offset changes during year two times when the Daylight Saving Time (DST) is ON or OFF.
So, the UTC time since epoch is always the same at any given point of time and in part of the world. But when we apply the DST enabled timezone rules then the instant is not a fixed number and it moves during a certain part of the year in that timezone.
For example, suppose we move the clock back one hour from 2 a.m. to 1 a.m. at the end of daylight savings time. In this case, 1:30 a.m. would occur twice, causing ambiguity.
OffsetDateTime doesn’t account for this case but
OffsetDateTime is an immutable representation of a date-time value, to nanosecond precision, with an offset from UTC/Greenwich in the ISO-8601 calendar system. As it depends on the offset, not on timezone, the offset values do not change with the dynamic timezone rules.
An instance of
OffsetDateTime always represents a unique instant on the timeline and so it is a great fit in usecases where we want to have timezone independent timestamps. For example, we can use
OffsetDateTime to store the timestamps in the database or send the timestamp values in XML documents over the network.
OffsetDateTime class combines the LocalDateTime class with the ZoneOffet class. The given below is a Java program to get the current UTC time to store in the database.
OffsetDateTime now = OffsetDateTime.now(ZoneOffset.of("UTC"));
Similar to OffsetDateTime, this class also represents a date-time with a time-zone in the ISO-8601 calendar system. The difference is that ZonedDateTime follows the changes in the DST rules and can have different offsets based on the time (summer/winter) of the year.
The ZonedDateTime class, in effect, combines the LocalDateTime class with the ZoneId class. Below is a Java program to get the current timestamp adjusted by currently effective zone offset in locations in “America/Los_Angeles” timezone.
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Los_Angeles"));
If we summarize the whole discussion in one sentence then ZonedDateTime is fully DST-aware and honors the daylight savings adjustments, and OffsetDateTime represents an offset adjusted instant from GMT/UTC (no timezone information).
Use OffsetDateTime to store unique instants in the universal timelines irrespective of the timezones, such as keeping the timestamps in the database or transferring information to remote systems worldwide.
Use ZonedDateTime for displaying timestamps to users according to their local timezone rules and offsets.
Happy Learning !!