Java8では、ZoneId.default()
を使用するとシステムのデフォルトZoneId
を取得できますが、デフォルトのZoneOffset
を取得するにはどうすればよいですか?
ZoneId
にはいくつかの「ルール」があり、各ルールにはZoneOffset
があります。つまり、ZoneId
には複数のZoneOffset
があります
OffsetDateTime.now().getOffset()
ただし、UTCからの単なるオフセットではなく、タイムゾーンを使用する必要があります。
ZoneId.systemDefault()
offset-from-UTC は単なる時間、分、秒の数であり、それ以上ではありません。
タイムゾーン は、特定の地域の人々が使用するオフセットの過去、現在、および将来の変更の履歴です。タイムゾーンには、 サマータイム(DST) などの異常を処理する一連のルールがあり、特定の期間にオフセットがシフトします。
タイムゾーン=(オフセット履歴+異常の規則)
したがって、ゾーンを使用する方がよい既知の場合。
リージョンのオフセットは時間とともに変化します。たとえば、 米国のDST は、約半年間オフセットを1時間シフトし、その年の後半にその時間をオフセットに戻します。タイムゾーンの全体的な目的は、これらのシフトをオフセットで文書化することです。
したがって、実際には、日時なしでオフセットを要求しても意味がありません。 America/Los_Angeles
では、たとえば今年の一部ではオフセットは-08:00
ですが、年の別の部分ではDST中の-07:00
です。
OffsetDateTime
OffsetDateTime
として瞬間を指定して、 ZoneOffset
を抽出しましょう。
OffsetDateTime odt = OffsetDateTime.now ();
ZoneOffset zoneOffset = odt.getOffset ();
odt.toString():2017-01-02T15:19:47.162-08:00
zoneOffset.toString():-08:00
そのnow
メソッドは、実際にはJVMの現在のデフォルトタイムゾーンを暗黙的に適用しています。希望する/予想されるタイムゾーンを指定して、常に明示的にすることをお勧めします。現在のデフォルトゾーンが必要な場合でも、意図を明確にするために明示的に言ってください。プログラマーでよく発生するように、デフォルトを意図したのか、タイムゾーンを考慮しなかったのかについてのあいまいさを排除します。 ZoneId.systemDefault
を呼び出します。
OffsetDateTime odt = OffsetDateTime.now ( ZoneId.systemDefault () );
ZoneOffset zoneOffset = odt.getOffset ();
ZoneId.systemDefault()。toString():America/Los_Angeles
odt:2017-01-02T15:19:47.162-08:00
zoneOffsetOfOdt:-08:00
デフォルトゾーンに依存する場合の注意:このデフォルトは、JVM内の任意のスレッドのコードによっていつでも変更できます。重要な場合は、ユーザーに目的のタイムゾーンを尋ねます。
合計秒数として、その時間をオフセットに求めることができます。
int offsetSeconds = zoneOffset.getTotalSeconds ();
offsetSeconds:-28800
ZonedDateTime
別の例:おそらく、ケベックでの今年のクリスマスにオフセットがどうなるか知りたいと思うでしょう。タイムゾーンAmerica/Montreal
を指定し、 ZonedDateTime
を取得し、そのオフセットをZoneOffset
オブジェクトとして要求します。
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate ld = LocalDate.of( 2017 , 12 , 25 );
ZonedDateTime zdtXmas = ld.atStartOfDay( z );
ZoneOffset zoneOffsetXmas = zdtXmas.getOffset();
zdtXmas.toString():2017-12-25T00:00-05:00 [アメリカ/モントリオール]
zoneOffsetXmas.toString():-05:00
zoneOffsetXmas.getTotalSeconds():-18000
ZoneId
Yanysのコメントで示唆されているように、ZoneId
として瞬間を渡すことにより、特定のZoneOffset
の Instant
を調べることができます。 Instant
クラスは、 UTC のタイムライン上の瞬間を、 ナノ秒 (小数部の最大9桁)の解像度で表します。
これは、同じ目的地への単なる別のルートです。前述のOffsetDateTime
およびZonedDateTime
と同様に、(a)タイムゾーンと(b)瞬間を指定しています。
Instant instant = zdtXmas.toInstant();
ZoneOffset zo = z.getRules().getOffset( instant );
ZoneId:America/Montreal at instant:2017-12-25T05:00:00Z ZoneOffsetは:-05:00
これらすべての例の IdeOne.comでのライブコード をご覧ください。
ZoneOffset.systemDefault
–バグまたは機能?ZoneOffset
のサブクラスであるZoneId
クラスは、 systemDefault
メソッドを継承するものとして文書化されています。ただし、これは実際には機能しません。
ZoneOffset zoneOffset = ZoneOffset.systemDefault() ; // Fails to compile.
エラー:互換性のないタイプ:ZoneIdはZoneOffsetに変換できません
このコンパイルの失敗がバグなのか機能なのかはわかりません。上で説明したように、日付と時刻のデフォルトオフセットを要求することは私には意味がないようです。したがって、おそらくZoneOffset.systemDefault
は実際に失敗するはずです。しかし、ドキュメントには説明が必要です。
この問題に対処するためにドキュメントの失敗に関するバグを報告しようとしましたが、あきらめて、そのようなバグレポートをどこでどのように提出するかを判断できませんでした。
Java.time フレームワークは、Java 8以降に組み込まれています。これらのクラスは、 Java.util.Date
、 Calendar
、& SimpleDateFormat
などの厄介な古い legacy date-timeクラスに取って代わります。
Joda-Time プロジェクトは、現在 メンテナンスモード にあり、 Java.time クラスへの移行を推奨しています。
詳細については、 Oracle Tutorial を参照してください。また、Stack Overflowで多くの例と説明を検索してください。指定は JSR 31 です。
Java.timeオブジェクトをデータベースと直接交換できます。 JDBC 4.2 以降に準拠する JDBCドライバー を使用します。文字列やJava.sql.*
クラスは必要ありません。
Java.timeクラスはどこで入手できますか?
ThreeTen-Extra プロジェクトは、追加のクラスでJava.timeを拡張します。このプロジェクトは、Java.timeに将来追加される可能性のある証明の場です。 Interval
、 YearWeek
、 YearQuarter
、および more などの便利なクラスがあります。