web-dev-qa-db-fra.com

Quelle est la différence entre Java 8 ZonedDateTime et OffsetDateTime?

J'ai lu la documentation, mais je ne parviens toujours pas à utiliser l'un ou l'autre:

Selon la documentation, OffsetDateTime devrait être utilisé lors de l'écriture de la date dans la base de données, mais je ne comprends pas pourquoi.

131
Zhenya

Q: Quelle est la différence entre Java 8 ZonedDateTime et OffsetDateTime?

Les javadocs disent ceci:

"OffsetDateTime, ZonedDateTime et Instant stockent tous un instant sur la précision temporelle en nanosecondes. Instant est le plus simple, simplement représentant l’instant. OffsetDateTime ajoute à l’instant le décalage par rapport à UTC/Greenwich, ce qui permet d’obtenir la date et l’heure locales. ZonedDateTime ajoute les règles de fuseau horaire complètes. "

Source: https://docs.Oracle.com/javase/8/docs/api/Java/time/OffsetDateTime.html

Ainsi, la différence entre OffsetDateTime et ZonedDateTime est que cette dernière inclut les règles qui couvrent les réglages de l'heure d'été et diverses autres anomalies.

Dit simplement:

fuseau horaire = ( décalage par rapport à l'heure UTC + règles relatives aux anomalies)


Q: Selon la documentation OffsetDateTime devrait être utilisé lors de l'écriture de la date dans la base de données, mais je ne comprends pas pourquoi.

Les dates avec des décalages horaires locaux représentent toujours les mêmes instants dans le temps et ont donc un ordre stable. En revanche, la signification des dates avec des informations de fuseau horaire complet est instable compte tenu des ajustements apportés aux règles pour les fuseaux horaires respectifs. (Et cela arrive, par exemple pour les valeurs date-heure dans le futur.) Donc, si vous stockez puis récupérez un ZonedDateTime, l'implémentation a un problème:

  • Il peut stocker le décalage calculé ... et l'objet récupéré peut alors avoir un décalage incohérent avec les règles en vigueur pour l'ID de zone.

  • Il peut ignorer le décalage calculé ... et l'objet récupéré représente alors un point différent dans la chronologie absolue/universelle de celui qui a été stocké.

Si vous utilisez la sérialisation d'objet Java, l'implémentation Java 9 adopte la première approche. C'est sans doute la façon "plus correcte" de gérer cela, mais cela ne semble pas être documenté. (Les pilotes JDBC et les liaisons ORM prennent probablement des décisions similaires et, espérons-le, prennent les bonnes décisions.)

Mais si vous écrivez une application qui stocke manuellement les valeurs de date/heure, ou qui repose sur Java.sql.DateTime, traiter des complications d'un identifiant de zone est ... quelque chose à éviter. D'où le conseil.

Notez que les dates dont la signification/l'ordre est instable dans le temps peuvent être problématiques pour une application. Et comme les modifications apportées aux règles de zone constituent un cas Edge, les problèmes risquent de surgir à des moments inattendus.


Une deuxième (possible) raison du conseil est que la construction d'un ZonedDateTime est ambiguë à certains moments. Par exemple, dans la période où vous "remettez les horloges", la combinaison d'une heure locale et d'un identifiant de zone peut vous donner deux décalages différents. Le ZonedDateTime choisira systématiquement un sur l'autre ... mais ce n'est pas toujours le bon choix.

Cela pourrait maintenant poser problème pour toutes les applications construisant ainsi ZonedDateTime valeurs. Mais du point de vue de la construction d’une application d’entreprise, l’enjeu majeur (éventuellement incorrect) ZonedDateTime persiste et est utilisé ultérieurement.

160
Stephen C