Почему
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
распечатать false
?
Я ожидал бы, что оба zonedDateTimes будут равны.
Почему
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
распечатать false
?
Я ожидал бы, что оба zonedDateTimes будут равны.
Ответ исходит из javadoc ZoneId
...
A ZoneId используется для определения правил, используемых для преобразования между Instant и LocalDateTime. Существует два разных типа ID:
- Фиксированные смещения - полностью разрешенное смещение от UTC/Greenwich, которое использует одинаковое смещение для всех локальных дат
- Географические регионы - область, где применяется определенный набор правил для определения смещения от UTC/Greenwich.
Большинство фиксированных смещений представлены ZoneOffset. Вызов нормализованного() на любой ZoneId будет отображаться фиксированный идентификатор смещения как ZoneOffset.
... и из javadoc ZoneId#of
:
Этот метод анализирует идентификатор, создающий ZoneId или ZoneOffset. ZoneOffset возвращается, если идентификатор "Z" или начинается с "+" или "-" .
Идентификатор аргумента указывается как "UTC"
, поэтому он возвращает ZoneId
со смещением, которое также представлено в строковой форме:
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(now.withZoneSameInstant(ZoneId.of("UTC")));
Выходы:
2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]
Когда вы используете метод equals
для сравнения, вы проверяете эквивалентность объекта. Из-за описанной разницы результат оценки false
.
Когда метод normalized()
используется, как предлагается в документации, сравнение с использованием equals
будет возвращать true
, как normalized()
вернет соответствующий ZoneOffset
:
Нормализует идентификатор временной зоны, где возможно, возможно, создает ZoneOffset.
now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true
Как указано в документации, если вы используете "Z"
или "+0"
в качестве входного id, of
будет возвращать ZoneOffset
напрямую, и нет необходимости вызывать normalized()
:
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true
Чтобы проверить , если они сохраняют одно и то же время, вы можете вместо этого использовать isEqual
:
now.withZoneSameInstant(ZoneOffset.UTC)
.isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true
Пример
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"))));
Вывод:
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
Если вы поместите оба из них в String, вы увидите, что первый из них 2016-09-15T09: 01:13.816Z, а второй - 2016-09-15T09: 01:13.816Z [UTC] они на самом деле одинаковы, но с zoneID вы получаете один дополнительный [UTC]
EDIT: проверьте ответ @DVarga, чтобы получить его так, как вы хотите