Joda-Time ライブラリにはさまざまな日時クラスが含まれています
DateTime --JDKカレンダーの不変の置換
DateMidnight -時刻が深夜に強制される日付を表す不変クラス
LocalDateTime -ローカルの日付と時刻を表す不変のクラス(タイムゾーンなし)
階層化アプリケーションでこれらのクラスをどのように使用しているのでしょうか。
アプリケーションがタイムゾーンを管理する必要がなく、常にUTCで時間を安全に想定できるように、(少なくともサービスレイヤーで)LocalDateTimeを使用するほとんどすべてのインターフェイスを使用することには利点があります。その後、私のアプリはDateTimeを使用して、実行フローの最初の時点でタイムゾーンを管理できます。
また、DateMidnightがどのシナリオで役立つのか疑問に思っています。
アプリケーションがタイムゾーンを管理する必要がなく、常にUTCで時間を安全に想定できるように、(少なくともサービスレイヤーで)LocalDateTimeを使用するほとんどすべてのインターフェイスを使用することには利点があります。
ここであなたの考え方が理解できるかわかりません。 LocalDateTime
とDateTime
は、まったく異なる2つの概念を表しています。 LocalDateTime
に暗黙のUTCタイムゾーンがあるわけではありません。実際にはnoタイムゾーンがあります(内部的にはDateTime
として表される場合があります。 UTCタイムゾーンですが、これは単なる実装の詳細であり、それを使用するプログラマーには関係ありません)。
APIドキュメントで確認できます それに対して、DateTime
は "Instant
"(世界のタイムラインのポイント、物理的概念)、LocalDateTime
はそのようなことではありません。 LocalDateTime
は実際には Partial
、(「市民」の概念)、別のクラス階層で。クラス名は、残念ながら、LocalDateTime
がDateTime
の特殊化であると思わせるかもしれません。そうではありません。
LocalDateTime
はペアと見なす必要があります{Date
(Y/M/D
); Time
(hh:mm:ss.msec
)}、時間関連データの「市民」標準表現に対応する一連の数値。 LocalDateTime
が与えられた場合、それを直接DateTime
に変換することはできません。タイムゾーンを指定する必要があります、そして、その変換は私たちを別の種類のエンティティに連れて行きます。 (アナロジー:Javaの文字列とバイトストリーム:それらの間で変換するには、概念的に異なるため、文字セットエンコーディングを指定する必要があります)
アプリケーションでどちらを使用するか...議論の余地がある場合もありますが、Jodatimeの概念を理解すれば、十分に明確になることがよくあります。また、IMOは「レイヤー」とはあまり関係がなく、おそらくユースケースやシナリオとは関係がありません。
自明ではない-borderline-の例:あなたはGoogleで働いており、カレンダーをプログラミングしています。日時を含むイベントをユーザーに管理(追加、表示、変更)させる必要があります(繰り返し発生するイベントは無視します)。たとえば、「2019年7月3日に医師との約束があります。午前10時」。ソフトウェアレイヤーで使用する日時エンティティは何ですか(このユースケースの場合)?私は言うだろう:LocalDateTime
。ユーザーは実際には物理的な時点ではなく、常用時を扱っているためです。つまり、手首または自宅に時計を表示する日付と時刻です。彼はタイムゾーンについても考えていません(世界中を旅しているユーザーの特殊なケースは無視しましょう...)そして、ビジネスとプレゼンテーション層では、LocalDateTime
が適切なエンティティのように見えます。
ただし、別のシナリオ、つまりリマインダーもコーディングする必要があるとします。 Googleの内部スケジューラは、ユーザーが保存したイベントがN分後であることを検出すると、ユーザーにリマインダーを送信する必要があります。ここで、「N分後」は完全に「物理的な」時間の概念であるため、ここでは「ビジネス層」はDateTime
を扱います。たとえば、いくつかの選択肢があります。イベントはLocalDateTime
としてDBに保存されました(つまり、タイムゾーンなしの日時のみ-UTCタイムスタンプを頻繁に使用してそれを表しますが、これは実装の詳細です)。このシナリオ(これのみ)では、それをDateTime
としてロードする必要があり、おそらくユーザーのプロファイルからタイムゾーンを使用して変換します。
leonbloyによる回答 は正しく、非常に重要です。 Joda-Timeプロジェクトを置き換えるJava.timeクラスに翻訳しているだけです。
タイムラインの特定の瞬間:
Instant
で表されます。OffsetDateTime
で表されます。ZonedDateTime
で表されます。これらはすべて、Joda-TimeのInstant
&DateTime
クラスを置き換えます。これらのJava.timeクラスはすべて、Joda-Timeで使用されるミリ秒に対して nanoseconds の解像度を持っています。
真夜中の場合、Joda-Timeプロジェクトは、「真夜中」は漠然とした非生産的な概念であると結論付けました。真夜中関連のクラスと真夜中は、Joda-Timeの以降のバージョンではすべて非推奨になり、「その日の最初の瞬間」という実用的な概念に置き換えられました。
Java.timeクラスは、「その日の最初の瞬間」アプローチを使用して、同じレッスンを受けました。 atStartOfDay
などのJava.timeクラスでLocalDate
メソッドを探します。
1日が00:00から始まると思い込まないでください。夏時間(DST)などの異常は、1日が01:00などの他の時間に開始される可能性があることを意味します。
ZonedDateTime zdt =
LocalDate.of( 2017 , Month.MARCH , 12 ) // Instantiate a date-only value without time zone.
.atStartOfDay( ZoneId.of( "America/Havana" ) ) ; // Cuba jumps from 00:00 to 01:00 on Spring DST cut-over.
たとえば、キューバが春の夏時間のカットオーバーで午前1時にどのように1日を開始するかをご覧ください。
zdt:2017-03-12T01:00-04:00 [アメリカ/ハバナ]
タイムライン上の実際の瞬間ではなく、約26〜27時間の範囲で起こりうる瞬間の漠然とした考えを表すには、LocalDateTime
を使用します。このクラスには、UTCからのオフセットまたはタイムゾーンが意図的に含まれていません。
LocalDateTime ldt = LocalDateTime.of( 2017 , Month.JANUARY , 23 , 1 , 2 , 3 , 0 ) ;
ビジネスコンテキストが特定のタイムゾーンを暗示している場合は、それを適用してZonedDateTime
を取得できます。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ; // Determine a specific point on timeline by providing the context of a time zone.
Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは、厄介な古い legacy などの日時クラスに取って代わります。 Java.util.Date
、 Calendar
、& SimpleDateFormat
。
Joda-Time プロジェクトは、現在 メンテナンスモード であり、 Java.time クラスへの移行をアドバイスします。
詳細については、 Oracleチュートリアル を参照してください。そして、StackOverflowで多くの例と説明を検索してください。仕様は JSR 31 です。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、Java.timeを追加のクラスで拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある試験場です。 Interval
、 YearWeek
、 YearQuarter
などの便利なクラスがここにあります。 、および more 。