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.
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 equals
true
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