Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 equality of UTC and Zulu time?

Tags:

As far I could research, UTC and Zulu are the same. However I'm running in difficulties comparing two ZonedDateTimes I receive from different sources in my code. The following code illustrates the problem:

@Test
public void equalsOnTimezone() throws Exception {
    ZonedDateTime zdtUtc = ZonedDateTime.of(2015, 2, 1, 14, 30, 0, 0, ZoneId.of("UTC"));
    ZonedDateTime zdtZ = ZonedDateTime.of(2015, 2, 1, 14, 30, 0, 0, ZoneId.of("Z"));
    assertEquals(zdtUtc, zdtZ); // will fail
}

The problem:

java.lang.AssertionError: expected:<2015-02-01T14:30Z[UTC]> but was:<2015-02-01T14:30Z>

And what will be the correct way to create and compare UTC based values then?

According to W3C Date and Time Formats:

Times are expressed in UTC (Coordinated Universal Time), with a special UTC designator ("Z").

like image 786
Dag Avatar asked Feb 01 '15 13:02

Dag


1 Answers

Comparing zone IDs rather than offsets

According to the source code, ZonedDateTime::equals uses ZoneId::equals to compare the zone id component, and that in turn compares the ids rather than the offsets.

If you want two ZonedDateTime with "different but equivalent" zone ids to compare as equal, you should create them like this, calling ZoneId::normalized.

ZonedDateTime zdtUtc = ZonedDateTime.of(
    2015, 2, 1, 14, 30, 0, 0, ZoneId.of("UTC").normalized());
ZonedDateTime zdtZ = ZonedDateTime.of(
    2015, 2, 1, 14, 30, 0, 0, ZoneId.of("Z").normalized());

I think this is a case where your expectations (based on the W3C documentation for the string representations) don't correspond to the documented semantics of the Java classes. In such cases, the Javadoc is definitive.

(This is not a Java 8 bug, IMO.)

like image 71
Stephen C Avatar answered Oct 02 '22 22:10

Stephen C