Почему ZoneOffset.Мирового!= ZoneId.из ("UTC")?


почему

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

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

Я ожидал бы оба ZonedDateTime случаях должны быть равны.

2 66

2 ответа:

ответ от javadoc из ZoneId (выделено мной) ...

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

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

большинство фиксированных смещений представлены ZoneOffset. вызов нормализуется() на любом ZoneId будет гарантировать, что будет представлен фиксированный идентификатор смещения как ZoneOffset.

... и от javadoc из ZoneId#of (выделено мной):

этот метод анализирует идентификатор, создавая ZoneId или ZoneOffset. A ZoneOffset возвращается, если идентификатор 'Z', или начинается с '+' или '-'.

идентификатор аргумента указан как "UTC", поэтому он вернет a 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

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

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