web-dev-qa-db-ja.com

Java 8 ZonedDateTimeとOffsetDateTimeの違いは何ですか?

私はドキュメントを読みましたが、どちらを使用すべきかはまだわかりません。

ドキュメントによると、データベースに日付を書き込むときにOffsetDateTimeを使用する必要がありますが、その理由はわかりません。

131
Zhenya

Q:Java 8 ZonedDateTimeとOffsetDateTimeの違いは何ですか?

Javadocsはこう言います:

"OffsetDateTimeZonedDateTime、およびInstantはすべて、タイムライン上の瞬間をナノ秒の精度で保存します。Instantは最も単純で、単純ですインスタントを表します。OffsetDateTimeは、ローカル日時を取得できるUTC /グリニッジからのオフセットをインスタントに追加します。ZonedDateTimeは、完全なタイムゾーン規則を追加します。 "

ソース: https://docs.Oracle.com/javase/8/docs/api/Java/time/OffsetDateTime.html

したがって、OffsetDateTimeZonedDateTimeの違いは、後者には夏時間調整やその他のさまざまな異常をカバーするルールが含まれていることです。

簡単に言うと:

タイムゾーン =( TCからのオフセット +異常のルール)


Q:ドキュメントによると、OffsetDateTimeを使用してデータベースに日付を書き込む必要がありますが、その理由はわかりません。

ローカルタイムオフセットのある日付は、常に同じ時点を表しているため、順序は安定しています。対照的に、完全なタイムゾーン情報を持つ日付の意味は、それぞれのタイムゾーンのルールの調整に直面して不安定です。 (そして、これらは起こります;例えば、将来の日時の値のため。)したがって、ZonedDateTimeを保存してから取得すると、実装に問題があります:

  • 計算されたオフセットを保存できます...そして、取得されたオブジェクトは、ゾーンIDの現在のルールと矛盾するオフセットを持つ場合があります。

  • 計算されたオフセットを破棄することができます...そして、取得されたオブジェクトは、保存されたものとは異なる絶対/普遍的なタイムラインのポイントを表します。

Javaオブジェクトのシリアル化を使用する場合、Java 9実装は最初のアプローチを取ります。これはおそらくこれを処理する「より正しい」方法ですが、文書化されていないようです。 (JDBCドライバーとORMバインディングはおそらく同様の決定を行っており、うまくいけばそれを正しくしているでしょう。)

ただし、日付/時刻の値を手動で保存するアプリケーション、またはJava.sql.DateTimeに依存するアプリケーションを作成している場合、zone-idの複雑さを処理することは、おそらく避けるべきものです。したがって、アドバイス。

意味/順序が時間とともに不安定になる日付は、アプリケーションにとって問題になる可能性があることに注意してください。また、ゾーンルールの変更はエッジの場合であるため、予期しないときに問題が発生する可能性があります。


アドバイスの(考えられる)2番目の理由は、ZonedDateTimeの構築が特定のポイントで曖昧であることです。たとえば、「クロックを戻す」期間中に、ローカル時間とゾーンIDを組み合わせると、2つの異なるオフセットが得られます。 ZonedDateTimeは一貫して一方を選択しますが、これが常に正しい選択とは限りません。

これは、ZonedDateTime値をそのように構築するアプリケーションにとっては問題になる可能性があります。しかし、エンタープライズアプリケーションを構築する誰かの観点から見ると、(おそらく正しくない)ZonedDateTime値が永続的であり、後で使用される場合、より大きな問題になります。

160
Stephen C