Was ist der Unterschied zwischen ZoneOffset.UTC und ZoneId.of(“UTC”)?

Lesezeit: 3 Minuten

Benutzer-Avatar
Johannes Flügel

Warum tut

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

ausdrucken false?

Ich würde beides erwarten ZonedDateTime Instanzen gleich sein.

  • Ich habe eine Folgefrage gestellt: stackoverflow.com/questions/69972061

    – Wankog

    15. November 2021 um 9:26 Uhr

Benutzer-Avatar
DVarga

Die Antwort kommt von der javadoc von ZoneId (Hervorhebung von mir) …

Eine ZoneId wird verwendet, um die Regeln zu identifizieren, die zum Konvertieren zwischen einem Instant und einem LocalDateTime verwendet werden. Es gibt zwei verschiedene ID-Typen:

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

Die meisten festen Offsets werden durch ZoneOffset dargestellt. Das Aufrufen von normalized() für eine beliebige ZoneId stellt sicher, dass eine feste Offset-ID als ZoneOffset dargestellt wird.

… und von der javadoc von ZoneId#of (Hervorhebung von mir):

Diese Methode analysiert die ID und erzeugt eine ZoneId oder einen ZoneOffset. Ein ZoneOffset wird zurückgegeben, wenn die ID „Z“ ist oder mit „+“ oder „-“ beginnt..

Die Argument-ID ist angegeben als "UTC"daher wird a zurückgegeben ZoneId mit einem Offset, der auch in der Zeichenfolgenform 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]

Wie Sie die verwenden equals Methode zum Vergleich, Sie auf Objektäquivalenz prüfen. Aufgrund des beschriebenen Unterschieds ist das Ergebnis der Auswertung false.

Wenn der normalized() Methode verwendet wird, wie in der Dokumentation vorgeschlagen, der Vergleich mit equals wird zurückkehren truewie normalized() wird das entsprechende zurückgeben ZoneOffset:

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 die Dokumentation besagt, wenn Sie verwenden "Z" oder "+0" als Eingabe-ID, of werde die zurückgeben ZoneOffset direkt und es ist kein Anruf erforderlich normalized():

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

Überprüfen wenn sie die gleiche Datumszeit speicherndu kannst den … benutzen isEqual Methode stattdessen:

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

  • Die Dokumente sagen auch: “Wenn die Zonen-ID gleich ‘GMT’, ‘UTC’ oder ‘UT’ ist, dann ist das Ergebnis eine ZoneId mit derselben ID und Regeln, die ZoneOffset.UTC entsprechen.” Gleiche ID und Regeln, aber unterschiedliches Verhalten. ZoneId.of("Z") gibt Ihnen ZoneOffset.UTC aber ZoneId.of("UTC") gibt dir ein ZoneId (das ist nicht ZoneOffset.UTC). Diese API ist, gelinde gesagt, nicht intuitiv.

    – Adam Millerchip

    6. März 2020 um 1:42 Uhr


  • …die API ist eine Katastrophe.

    – Andries

    5. November 2021 um 11:39 Uhr

1352190cookie-checkWas ist der Unterschied zwischen ZoneOffset.UTC und ZoneId.of(“UTC”)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy