Was ist der Unterschied zwischen ZonedDateTime und OffsetDateTime?

155

Ich habe die Dokumentation gelesen, kann aber immer noch nicht feststellen, wann ich das eine oder andere verwenden soll:

Laut Dokumentation OffsetDateTimesollte beim Schreiben des Datums in die Datenbank verwendet werden, aber ich verstehe nicht warum.

Zhenya
quelle
4
Grundsätzlich ZonedDateTimeenthält a auch Informationen zu Zeitzonen, einschließlich Sommerzeitumschaltung usw. von dem, was ich gelesen habe.
14.

Antworten:

187

F: Was ist der Unterschied zwischen Java 8 ZonedDateTime und OffsetDateTime?

Die Javadocs sagen Folgendes:

" OffsetDateTime, ZonedDateTimeund Instantalle speichern einen Moment auf der Zeitachse mit einer Genauigkeit von Nanosekunden. Instantist der einfachste, der einfach den Moment darstellt. OffsetDateTimeFügt dem Moment den Versatz von UTC / Greenwich hinzu, wodurch die lokale Datums- und Uhrzeitangabe erhalten werden kann. ZonedDateTimeFügt Vollzeit hinzu -Zonenregeln. "

Quelle: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html

Der Unterschied zwischen OffsetDateTimeund ZonedDateTimebesteht darin, dass letzteres die Regeln enthält, die Anpassungen der Sommerzeit und verschiedene andere Anomalien abdecken.

Einfach ausgedrückt:

Zeitzone = ( Versatz von UTC + Regeln für Anomalien)


F: Laut Dokumentation OffsetDateTimesollte beim Schreiben des Datums in die Datenbank verwendet werden, aber ich verstehe nicht warum.

Daten mit lokalen Zeitversätzen repräsentieren immer die gleichen Zeitpunkte und haben daher eine stabile Reihenfolge. Im Gegensatz dazu ist die Bedeutung von Datumsangaben mit vollständigen Zeitzoneninformationen angesichts von Anpassungen der Regeln für die jeweiligen Zeitzonen instabil. (Und diese passieren, z. B. für Datums- und Uhrzeitwerte in der Zukunft.) Wenn Sie also eine speichern und dann abrufen, hat ZonedDateTimedie Implementierung ein Problem:

  • Es kann den berechneten Versatz speichern ... und das abgerufene Objekt kann dann einen Versatz haben, der nicht mit den aktuellen Regeln für die Zonen-ID übereinstimmt.

  • Der berechnete Versatz kann verworfen werden ... und das abgerufene Objekt repräsentiert dann einen anderen Punkt in der absoluten / universellen Zeitleiste als den gespeicherten.

Wenn Sie die Java-Objektserialisierung verwenden, verfolgt die Java 9-Implementierung den ersten Ansatz. Dies ist wohl die "korrektere" Art, damit umzugehen, aber dies scheint nicht dokumentiert zu sein. (JDBC-Treiber und ORM-Bindungen treffen vermutlich ähnliche Entscheidungen und machen es hoffentlich richtig.)

Wenn Sie jedoch eine Anwendung schreiben, in der Datums- / Zeitwerte manuell gespeichert werden oder auf die Sie angewiesen sind java.sql.DateTime, sollten Sie sich wahrscheinlich mit den Komplikationen einer Zonen-ID auseinandersetzen. Daher der Rat.

Beachten Sie, dass Daten, deren Bedeutung / Reihenfolge im Laufe der Zeit instabil ist , für eine Anwendung problematisch sein können. Und da Änderungen an Zonenregeln ein Randfall sind, können die Probleme zu unerwarteten Zeiten auftreten.


Ein (möglicher) zweiter Grund für den Rat ist, dass die Konstruktion von a ZonedDateTimean bestimmten Punkten nicht eindeutig ist. Wenn Sie beispielsweise in der Zeit, in der Sie die Uhren zurückstellen, eine Ortszeit und eine Zonen-ID kombinieren, können Sie zwei verschiedene Offsets erhalten. Die ZonedDateTimewerden konsequent übereinander wählen ... aber das ist nicht immer die richtige Wahl.

Dies könnte nun ein Problem für alle Anwendungen sein, die ZonedDateTimeauf diese Weise Werte erstellen . Aus der Sicht einer Person, die eine Unternehmensanwendung erstellt, ist dies jedoch ein größeres Problem, wenn die (möglicherweise falschen) ZonedDateTimeWerte dauerhaft sind und später verwendet werden.

Stephen C.
quelle