tl; dr
Instant
そしてLocalDateTime
2匹の全く異なる動物です:一つは瞬間を表し、他にはありません。
Instant
タイムラインの特定の時点である瞬間を表します。
LocalDateTime
日付と時刻を表します。しかし、タイムゾーンまたはUTCからのオフセットがないため、このクラスは瞬間を表すことができません。世界中のすべてのタイムゾーンの範囲である約26〜27時間の範囲に沿った潜在的な瞬間を表します。
誤った推定
LocalDateTime
人間のタイムゾーンを含む日付/時計表現です。
ステートメントが正しくありません:A LocalDateTime
にはタイムゾーンがありません。タイムゾーンがないことは、そのクラスの全体のポイントです。
そのクラスのドキュメントを引用するには:
このクラスは、タイムゾーンを格納または表しません。代わりに、誕生日に使用される日付の説明と、壁掛け時計に表示される現地時間を組み合わせたものです。オフセットやタイムゾーンなどの追加情報がなければ、タイムライン上のインスタントを表すことはできません。
つまりLocal…
、「ゾーン化されず、オフセットなし」を意味します。
Instant
An Instant
はUTCのタイムライン上の瞬間であり、1970 UTCの最初の瞬間のエポックからのナノ秒数です(基本的に、重要な詳細についてはクラスドキュメントを参照してください)。ビジネスロジック、データストレージ、およびデータ交換のほとんどはUTCで行う必要があるため、これは頻繁に使用される便利なクラスです。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
OffsetDateTime
クラスOffsetDateTime
classは、UTCの前後の時間数分秒のコンテキストで、瞬間を日時として表します。オフセットの量、時間、分、秒の数は、ZoneOffset
クラスによって表されます。
時間-分-秒の数がゼロの場合、OffsetDateTime
はUTCの瞬間を表し、Instant
ます。
ZoneOffset
このZoneOffset
クラスは、UTCからのオフセットまたはUTCからの時間数分秒の数である、UTCからのオフセットを表します。
あ ZoneOffset
は、時間、分、秒の数にすぎません。ゾーンははるかに多く、オフセットする名前と変更の履歴があります。したがって、ゾーンを使用することは、単なるオフセットを使用するよりも常に望ましい方法です。
ZoneId
タイムゾーンが表されZoneId
たクラス。
新しい日がパリの早い夜明けたとえば、はモントリオールよりも方ます。したがって、特定の地域の正午(太陽が真上にあるとき)をよりよく反映するように、時計の針を動かす必要があります。西ヨーロッパ/アフリカのUTCラインから東/西に離れるほど、オフセットが大きくなります。
タイムゾーンは、地域社会や地域で行われている調整や異常を処理するための一連のルールです。最も一般的な異常は、夏時間(DST)として知られている、あまりにも人気の高い狂気です。
タイムゾーンには、過去のルール、現在のルール、および近い将来に確認されるルールの履歴があります。
これらのルールは、予想よりも頻繁に変更されます。日時ライブラリのルール、通常は「tz」データベースのコピーを最新の状態に保つようにしてください。OracleがリリースするJava 8では、最新の状態を維持することが今までになく簡単になりました。 Timezone Updater Toolを。
指定適切なタイムゾーン名をの形式でContinent/Region
、のようなAmerica/Montreal
、Africa/Casablanca
またはPacific/Auckland
。決してなど2-4文字の略称を使用していないEST
か、IST
そのままではない真の時間帯ではなく、標準化、さらには一意ではありません(!)。
タイムゾーン=オフセット+調整規則
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
ZonedDateTime
ZonedDateTime
概念的にはInstant
、割り当てられたと考えてくださいZoneId
。
ZonedDateTime =(Instant + ZoneId)
特定の地域(タイムゾーン)の人々が使用する実時間で表示される現在の瞬間をキャプチャするには:
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`.
バックエンド、データベース、ビジネスロジック、データの永続性、データ交換のほぼすべてがUTCである必要があります。ただし、ユーザーに提示する場合は、ユーザーが期待するタイムゾーンに調整する必要があります。これは、これらの日時値の文字列表現を生成するために使用されるZonedDateTime
クラスとフォーマッタクラスの目的です。
ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ; // Standard ISO 8601 format.
を使用して、ローカライズされた形式でテキストを生成できますDateTimeFormatter
。
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
String outputFormatted = zdt.format( f ) ;
mardi 30 avril 2019à23 h 22 min 55 s heure de l'Inde
LocalDate
、LocalTime
、LocalDateTime
「ローカル」日時クラス、LocalDateTime
、LocalDate
、LocalTime
、生き物の異なる種類です。は、特定の地域やタイムゾーンに関連付けられていません。タイムラインとは関係ありません。それらを地域に適用してタイムライン上のポイントを見つけるまで、実際の意味はありません。
これらのクラス名の「ローカル」という言葉は、初心者にはわかりにくいかもしれません。単語は、特定の場所ではなく、任意の場所またはすべての場所を意味します。
したがって、ビジネスアプリの場合、「ローカル」タイプは、タイムライン上の特定の瞬間ではなく、可能性のある日付または時刻の一般的な概念を表すだけなので、あまり使用されません。ビジネスアプリは、請求書が到着した瞬間、輸送のために出荷された製品、従業員が雇われた瞬間、またはタクシーがガレージを離れた瞬間を気にする傾向があります。そのためInstant
、ビジネスアプリ開発者は、ZonedDateTime
最もよく使用するクラスを使用しています。
では、いつ使用しLocalDateTime
ますか?3つの状況:複数の場所に特定の日付と時刻を適用する場合、予定を予約する場合、または意図した未確定のタイムゾーンがある場合。これら3つのケースはいずれも、タイムライン上の特定の特定のポイントではなく、いずれも瞬間ではないことに注意してください。
1つの時刻、複数の瞬間
特定の日付の特定の時刻を表現したいが、タイムゾーン全体の複数の地域にそれを適用したい場合があります。
たとえば、「2015年12月25日の真夜中にクリスマスが始まる」はLocalDateTime
です。パリではモントリオールとは異なる瞬間に真夜中がストライキし、シアトルとオークランドでもストライキが異なります。
LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
LocalTime lt = LocalTime.MIN ; // 00:00:00
LocalTime ldt = LocalDateTime.of( ld , lt ) ; // Xmas morning anywhere.
別の例として、「Acme Companyは、世界中の各工場で昼休みが午後12時30分に始まるというポリシーを持っています」はLocalTime
です。本当の意味を持つためには、それをタイムラインに適用して、シュトゥットガルト工場で12:30、ラバト工場で12:30、またはシドニー工場で12:30の瞬間を把握する必要があります。
予約の予約
使用するもう1つの状況LocalDateTime
は、将来のイベントを予約する場合です(例:歯科医の予約)。これらの予定は、将来、政治家がタイムゾーンを再定義する危険を冒すのに十分遠い可能性があります。多くの場合、政治家は予告をほとんど与えないか、まったく警告さえしません。政治家の時計の使い方に関係なく「来年の1月23日午後3時」を意味する場合、瞬間を記録することはできません。その地域がサマータイムを採用または削除した場合、午後3時が午後2時または午後4時に変わることになります。例えば。
予定の場合は、a LocalDateTime
とa ZoneId
を別々に保管してください。後で、スケジュールLocalDateTime::atZone( ZoneId )
を生成するZonedDateTime
ときに、オブジェクトを生成するように呼び出して、その場で瞬間を決定します。
ZonedDateTime zdt = ldt.atZone( z ) ; // Given a date, a time-of-day, and a time zone, determine a moment, a point on the timeline.
必要に応じて、UTCに調整できます。Instant
からを抽出しZonedDateTime
ます。
Instant instant = zdt.toInstant() ; // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock time.
不明なゾーン
一部の人々はLocalDateTime
、タイムゾーンまたはオフセットが不明な状況で使用する場合があります。
私はこの事件を不適切で賢明ではないと考えています。ゾーンまたはオフセットが意図されているが不明な場合、データが不良です。これは、意図する通貨を知らずに製品の価格を保存するようなものです。良い考えではありません。
すべての日時タイプ
完全を期すために、Javaでの最新のタイプとレガシーのタイプの両方、およびSQL標準で定義されているタイプのすべての可能な日時タイプの表を以下に示します。これは、Instant
&LocalDateTime
クラスをより大きなコンテキストに配置するのに役立ちます。
JDBC 4.2の設計においてJavaチームが行った奇妙な選択に注目してください。彼らはすべてのjava.time時間をサポートすることを選択しました。もっともよく使われる2つのクラスInstant
&を除きZonedDateTime
ます。
しかし、心配する必要はありません。簡単に前後に変換できます。
変換していInstant
ます。
// Storing
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
変換していZonedDateTime
ます。
// Storing
OffsetDateTime odt = zdt.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;
// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZone( z ) ;
java.timeについて
java.timeのフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは面倒古い取って代わるレガシーのような日付時刻クラスをjava.util.Date
、Calendar
、& SimpleDateFormat
。
ジョダタイムプロジェクトは、今でメンテナンスモードへの移行をアドバイスjava.timeのクラス。
詳細については、Oracleチュートリアルを参照してください。スタックオーバーフローで多くの例と説明を検索してください。仕様はJSR 310です。
java.timeオブジェクトをデータベースと直接交換することができます。に準拠したJDBCドライバーを使用するJDBC 4.2以降に。文字列もjava.sql.*
クラスも必要ありません。
java.timeクラスはどこで入手できますか?
ThreeTen-エクストラプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、java.timeに将来追加される可能性があることを証明する場です。あなたはここにいくつかの有用なクラスのような見つけることがInterval
、YearWeek
、YearQuarter
、および多くを。