webentwicklung-frage-antwort-db.com.de

Warum ist ZoneOffset.UTC! = ZoneId.of ("UTC")?

Warum tut

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

false ausdrucken?

Ich würde erwarten, dass beide ZonedDateTime Instanzen gleich sind.

95

Die Antwort kommt von javadoc von ZoneId (Hervorhebung von mir) ...

Eine ZoneId wird verwendet, um die Regeln zu identifizieren, die zum Konvertieren zwischen Instant und LocalDateTime verwendet werden. Es gibt zwei verschiedene Arten von IDs:

  • Feste Offsets - Ein vollständig aufgelöster Offset von UTC/Greenwich, der für alle lokalen Datums- und Uhrzeitangaben denselben Offset verwendet
  • Geografische Regionen - Ein Bereich, in dem bestimmte Regeln zum Ermitteln des Versatzes von UTC/Greenwich gelten

Die meisten festen Offsets werden durch ZoneOffset dargestellt. Durch Aufrufen von normalized () für jede ZoneId wird sichergestellt, dass eine feste Versatz-ID als ZoneOffset dargestellt wird.

... und aus dem javadoc von ZoneId#of (Hervorhebung von mir):

Diese Methode analysiert die ID und erstellt eine ZoneId oder ein ZoneOffset. Ein ZoneOffset wird zurückgegeben, wenn die ID 'Z' ist oder mit '+' oder '-' beginnt .

Die Argument-ID wird als "UTC" angegeben. Daher wird ein ZoneId mit einem Offset zurückgegeben, der auch in der folgenden Zeichenfolge dargestellt wird:

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

Ausgänge:

2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]

Wenn Sie die equals -Methode zum Vergleich verwenden, überprüfen Sie die Objektäquivalenz . Aufgrund des beschriebenen Unterschieds lautet das Ergebnis der Auswertung false.

Wenn die in der Dokumentation vorgeschlagene Methode normalized() verwendet wird, gibt der Vergleich mit equalstrue zurück, da normalized() das entsprechende ZoneOffset zurückgibt:

Normalisiert die Zeitzonen-ID und gibt nach Möglichkeit ein ZoneOffset zurück.

now.withZoneSameInstant(ZoneOffset.UTC)
    .equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true

Wie in der Dokumentation angegeben, gibt "Z" oder "+0" als Eingabe-ID of das ZoneOffset direkt zurück, und es ist kein Aufruf erforderlich normalized():

now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true

Um zu überprüfen , ob sie das gleiche Datum und die gleiche Uhrzeit speichern , können Sie stattdessen die Methode isEqual verwenden:

now.withZoneSameInstant(ZoneOffset.UTC)
    .isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true

Probe

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"))));

Ausgabe:

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
138
DVarga