it-swarm.com.ru

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

Почему

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

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

Я ожидаю, что оба экземпляра ZonedDateTime будут равны.

88
Johannes Flügel

Ответ приходит от javadoc ZoneId (выделено мной) ...

ZoneId используется для определения правил, используемых для преобразования между Instant и LocalDateTime. Существует два разных типа идентификатора:

  • Фиксированные смещения - полностью разрешенное смещение от UTC/Гринвич, которое использует одинаковое смещение для всех локальных дат и времени
  • Географические регионы - область, к которой применяется определенный набор правил для нахождения смещения от UTC/Гринвич

Большинство фиксированных смещений представлены ZoneOffset. Вызов normalized () для любого 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" в качестве входного идентификатора, 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
129
DVarga