Qual è la differenza tra ZonedDateTime e OffsetDateTime?


155

Ho letto la documentazione, ma non riesco ancora a ottenere quando dovrei usare l'uno o l'altro:

Secondo la documentazione OffsetDateTimedovrebbe essere usato quando si scrive la data nel database, ma non capisco perché.


4
Fondamentalmente a ZonedDateTimecontiene anche informazioni sui fusi orari, tra cui la commutazione dell'ora legale ecc. Da quello che ho letto.
fge,

Risposte:


187

D: Qual è la differenza tra java 8 ZonedDateTime e OffsetDateTime?

I javadocs dicono questo:

" OffsetDateTime, ZonedDateTimee Instanttutti memorizzano un istante sulla linea temporale con precisione al nanosecondo. Instantè il più semplice, semplicemente rappresentando l'istante. OffsetDateTimeaggiunge all'istante l'offset da UTC / Greenwich, che consente di ottenere la data-ora locale. ZonedDateTimeaggiunge tempo pieno -zone regole ".

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

Quindi la differenza tra OffsetDateTimee ZonedDateTimeè che quest'ultima include le regole che coprono le regolazioni dell'ora legale e varie altre anomalie.

Dichiarato semplicemente:

Fuso orario = ( Offset-Da-UTC + Regole-per-anomalie)


D: Secondo la documentazione OffsetDateTimedovrebbe essere usato quando si scrive la data nel database, ma non capisco perché.

Le date con offset dell'ora locale rappresentano sempre gli stessi istanti nel tempo e quindi hanno un ordinamento stabile. Al contrario, il significato delle date con le informazioni complete sul fuso orario è instabile di fronte agli adeguamenti delle regole per i rispettivi fusi orari. (E ciò accade; ad es. Per i valori di data e ora in futuro.) Quindi, se si memorizza e si recupera ZonedDateTimeun'implementazione, si verifica un problema:

  • Può archiviare l'offset calcolato ... e l'oggetto recuperato potrebbe quindi avere un offset incompatibile con le regole correnti per l'ID zona.

  • Può scartare l'offset calcolato ... e l'oggetto recuperato rappresenta quindi un punto diverso nella linea temporale assoluta / universale rispetto a quello memorizzato.

Se si utilizza la serializzazione di oggetti Java, l'implementazione di Java 9 adotta il primo approccio. Questo è probabilmente il modo "più corretto" di gestirlo, ma questo non sembra essere documentato. (I driver JDBC e le associazioni ORM presumibilmente prendono decisioni simili e si spera che stiano andando bene.)

Ma se stai scrivendo un'applicazione che memorizza manualmente i valori di data / ora, o su cui fare affidamento java.sql.DateTime, affrontare le complicazioni di un id di zona è ... probabilmente qualcosa da evitare. Da qui il consiglio.

Si noti che le date il cui significato / ordinamento è instabile nel tempo possono essere problematiche per un'applicazione. E poiché le modifiche alle regole di zona sono un caso limite, i problemi possono emergere in momenti inaspettati.


Una (possibile) seconda ragione del consiglio è che la costruzione di a ZonedDateTimeè ambigua in determinati punti. Ad esempio nel periodo di tempo in cui si "ripristinano gli orologi", la combinazione di un'ora locale e un id di zona può darti due offset diversi. Lo ZonedDateTimesceglieranno costantemente uno sopra l'altro ... ma questa non è sempre la scelta corretta.

Ora, questo potrebbe essere un problema per tutte le applicazioni che costruiscono ZonedDateTimevalori in quel modo. Ma dal punto di vista di qualcuno che costruisce un'applicazione enterprise è un problema maggiore quando i ZonedDateTimevalori (possibilmente errati) sono persistenti e usati in seguito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.