web-dev-qa-db-ja.com

Java 8の新しいJava Date Time APIがDSTを処理しますか?

新しいJava 8 Date Time APIの使用を考えています。私は少しグーグルしましたが、Java)にはjodaTimeが適切な選択肢であることがわかりましたが、この新しいAPIがどのように機能するかを確認することに興味がありました。

私はすべての時間をUTC値でデータストアに保存し、ユーザーのタイムゾーンに基づいてローカルタイムゾーン固有の値に変換します。新しいJava Date Time APIの使用方法を示す多くの記事を見つけることができます。しかし、APIがDSTの変更を処理するかどうかわかりませんか?または、Dateを処理するより良い方法はありますか?

私は新しいDate APIを学習しているだけなので、DateTimeを処理し、Users TimeZoneに基づいて表示することについてのあなたの考えを聞いてみてください。

22
Raja

使用するクラスによって異なります。

  • Instantはグローバルタイムライン(UTC)上の瞬間的なポイントであり、タイムゾーンとは無関係です。
  • LocalDateLocalDateTimeにはタイムゾーンの概念はありませんが、now()を呼び出すと、正しい時刻が得られます。
  • OffsetDateTimeにはタイムゾーンがありますが、夏時間をサポートしていません。
  • ZonedDateTimeは完全なタイムゾーンをサポートしています。

それらの間の変換には通常タイムゾーンが必要なので、質問に答えます:

はい、Java 8日付/時刻can DSTを処理します、if使用しますそれは正しい。

38
Andreas

回答アンドレアス は正解です。

コード例

いくつかのコードでテストしてみましょう。 米国の夏時間 &カナダは2015年11月1日の02:00に期限が切れます。

「現地時間」の午前1時から始めましょう。タイムラインとは関係なく、タイムゾーンの問題を無視しています。 1時間追加すると、午前2時になります。理にかなっています。

LocalDateTime localDateTime = LocalDateTime.of( 2015 , Month.NOVEMBER , 1 , 1 , 0 ); // 1 AM anywhere. Not tied the timeline nor to any time zone.
LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours( 1 ); // 2 AM anywhere, in no particular time zone, ignoring DST.

次に、特定のタイムゾーンで具体的に取得します。その午前1時をどこでも取り、America/Los_Angeles(米国西海岸)のタイムゾーンに入れます。

ZoneId zoneId_LosAngeles = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime before = localDateTime.atZone( zoneId_LosAngeles ); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line.

ここで1時間追加して、何が得られるかを確認します。 DSTが無視された場合、午前2時になります。 DSTが順守されている場合、午前1時を取得します。午前2時になると、 実時間 が午前1時に戻りますが、UTCからのオフセットが新しくなります。これは口語的に "fall back" として秋(秋)に知られています。

ZonedDateTime after = before.plusHours( 1 ); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015.

コンソールにダンプします。

System.out.println( "localDateTime : " + localDateTime );
System.out.println( "localDateTimeOneHourLater : " + localDateTimeOneHourLater );
System.out.println( "before : " + before );
System.out.println( "after : " + after );

実行すると、この出力が得られます。タイムゾーンがない場合、1 AM + 1時間= 2 AM。これらは「ローカル」の日時値であり、UTCではないことに注意してください。それらは日付時刻のあいまいな考えのみを表し、タイムライン上の実際の瞬間ではありません。

localDateTime : 2015-11-01T01:00
localDateTimeOneHourLater : 2015-11-01T02:00

しかし、DSTの期限が切れる日にタイムゾーンが適用されると、異なる結果が得られます。時刻は01:00のままですが、 offset-from-UTC-07:00から-08:00に変更されることに注意してください。

before : 2015-11-01T01:00-07:00[America/Los_Angeles]
after : 2015-11-01T01:00-08:00[America/Los_Angeles]

おそらくこれは、UTCに調整すると、より明確になり、検証が容易になります。 beforeおよびafterオブジェクトに Instant オブジェクトとしてアクセスするだけで、これを行うことができます。 System.out.println 次に、 toString メソッドを暗黙的に呼び出します。

System.out.println( "before.toInstant : " + before.toInstant() );
System.out.println( "after.toInstant : " + after.toInstant() );

実行すると。

before.toInstant : 2015-11-01T08:00:00Z
after.toInstant : 2015-11-01T09:00:00Z

Java.timeについて

Java.time フレームワークはJava 8以降に組み込まれています。これらのクラスは厄介な古い レガシーに取って代わりますJava.util.DateCalendar 、& SimpleDateFormat などの日時クラス.

Joda-Time プロジェクトは現在 メンテナンスモード であり、 Java.time クラスへの移行を推奨しています。

詳細については、 Oracleチュートリアル を参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様は JSR 310 です。

Java.timeオブジェクトをデータベースと直接交換できます。 JDBC 4.2 以降に準拠した JDBCドライバー を使用します。文字列も、Java.sql.*クラスも必要ありません。

Java.timeクラスはどこで入手できますか?

ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性があることを証明する場です。 IntervalYearWeekYearQuartermore などの便利なクラスがここにあります。

29
Basil Bourque

はい、Java APIはDSTの変更を考慮します。

このチュートリアルでは、タイムゾーン間で日付を変換する方法と、日付を表すために適切なクラスを選択する方法について詳しく説明しています。 https://docs.Oracle.com/javase/tutorial/datetime/iso/timezones.html =

各ゾーンのルールを表すこのクラスも確認できます。 http://docs.Oracle.com/javase/8/docs/api/Java/time/zone/ZoneRules.html

特に、このメソッドは、特定のインスタントが夏時間であるかどうかを通知できます。 http://docs.Oracle.com/javase/8/docs/api/Java/time/zone/ZoneRules.html#isDaylightSavings -Java.time.Instant-

4
eugenioy