ZoneId describes a time-zone identifier and provides rules for converting between an Instant and a LocalDateTime . ZoneOffset describes a time-zone offset, which is the amount of time (typically in hours) by which a time zone differs from UTC/Greenwich.
ZoneOffset extends ZoneId and defines the fixed offset of the current time-zone with GMT/UTC, such as +02:00. This means that this number represents fixed hours and minutes, representing the difference between the time in current time-zone and GMT/UTC: LocalDateTime now = LocalDateTime.
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.
The answer comes from the javadoc of ZoneId
(emphasis mine) ...
A ZoneId is used to identify the rules used to convert between an Instant and a LocalDateTime. There are two distinct types of ID:
- Fixed offsets - a fully resolved offset from UTC/Greenwich, that uses the same offset for all local date-times
- Geographical regions - an area where a specific set of rules for finding the offset from UTC/Greenwich apply
Most fixed offsets are represented by ZoneOffset. Calling normalized() on any ZoneId will ensure that a fixed offset ID will be represented as a ZoneOffset.
... and from the javadoc of ZoneId#of
(emphasis mine):
This method parses the ID producing a ZoneId or ZoneOffset. A ZoneOffset is returned if the ID is 'Z', or starts with '+' or '-'.
The argument id is specified as "UTC"
, therefore it will return a ZoneId
with an offset, which also presented in the string form:
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(now.withZoneSameInstant(ZoneId.of("UTC")));
Outputs:
2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]
As you use the equals
method for comparison, you check for object equivalence. Because of the described difference, the result of the evaluation is false
.
When the normalized()
method is used as proposed in the documentation, the comparison using equals
will return true
, as normalized()
will return the corresponding ZoneOffset
:
Normalizes the time-zone ID, returning a ZoneOffset where possible.
now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true
As the documentation states, if you use "Z"
or "+0"
as input id, of
will return the ZoneOffset
directly and there is no need to call normalized()
:
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true
To check if they store the same date time, you can use the isEqual
method instead:
now.withZoneSameInstant(ZoneOffset.UTC)
.isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true
Sample
System.out.println("equals - ZoneId.of(\"UTC\"): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
System.out.println("equals - ZoneId.of(\"UTC\").normalized(): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())));
System.out.println("equals - ZoneId.of(\"Z\"): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("Z"))));
System.out.println("equals - ZoneId.of(\"+0\"): " + nowZoneOffset
.equals(now.withZoneSameInstant(ZoneId.of("+0"))));
System.out.println("isEqual - ZoneId.of(\"UTC\"): "+ nowZoneOffset
.isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))));
Output:
equals - ZoneId.of("UTC"): false
equals - ZoneId.of("UTC").normalized(): true
equals - ZoneId.of("Z"): true
equals - ZoneId.of("+0"): true
isEqual - ZoneId.of("UTC"): true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With