Подтвердить что ты не робот

Почему ZoneOffset.UTC!= ZoneId.of( "UTC" )?

Почему

ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
        .equals(now.withZoneSameInstant(ZoneId.of("UTC"))));

распечатать false?

Я ожидал бы, что оба zonedDateTimes будут равны.

4b9b3361

Ответ 1

Ответ исходит из 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

Ответ 2

Если вы поместите оба из них в String, вы увидите, что первый из них 2016-09-15T09: 01:13.816Z, а второй - 2016-09-15T09: 01:13.816Z [UTC] они на самом деле одинаковы, но с zoneID вы получаете один дополнительный [UTC]

EDIT: проверьте ответ @DVarga, чтобы получить его так, как вы хотите