Instant と LocalDateTime の違いは何ですか? 質問する

Instant と LocalDateTime の違いは何ですか? 質問する

私はそれを知っています:

  • インスタントは、むしろコンピューティングのための「技術的な」タイムスタンプ表現 (ナノ秒) です。
  • LocalDateTime は、人間向けに タイムゾーンを含む 日付/時刻表現です 。

それでも、最終的には、ほとんどのアプリケーションの使用例では、どちらも型として捉えることができると私は考えています。例: 現在、日付に基づいて次の実行を計算する必要があるバッチ ジョブを実行しており、これら 2 つの型の長所と短所を見つけるのに苦労しています (のナノ秒精度の利点と のInstantタイム ゾーン部分は別としてLocalDateTime)。

InstantまたはのみLocalDateTimeを使用する必要があるアプリケーションの例をいくつか挙げてください。

編集:LocalDateTime精度とタイムゾーンに関するドキュメントの誤読に注意してください。

ベストアンサー1

Java のすべての日付時刻型 (最新と旧の両方) の表

要約

InstantこれらはLocalDateTime全く異なる 2 つの動物です。一方は瞬間を表し、もう一方はそうではありません。

  • Instant瞬間、タイムライン内の特定のポイントを表します。
  • LocalDateTime日付と時刻を表します。ただし、タイムゾーンまたは UTC からのオフセットがないため、このクラスは瞬間を表すことができません。これは、世界中のすべてのタイムゾーンの範囲である約 26 ~ 27 時間の範囲に沿った潜在的な瞬間を表します。LocalDateTime値は本質的に曖昧です。

誤った推定

LocalDateTimeむしろ、人間のためのタイムゾーンを含む日付/時刻の表現です。

あなたの記述は間違っています: ALocalDateTimeタイムゾーンがありません。タイムゾーンがないのがそのクラスのポイントです。

そのクラスのドキュメントを引用すると:

このクラスは、タイムゾーンを保存または表すものではありません。代わりに、誕生日に使用される日付の説明と、壁掛け時計に表示される現地時間を組み合わせたものです。オフセットやタイムゾーンなどの追加情報なしでは、タイムライン上の瞬間を表すことはできません。

つまり、Local…「ゾーン分けなし、オフセットなし」という意味です。

Instant

ここに画像の説明を入力してください

アンInstantタイムライン上の瞬間UTC、カウントナノ秒1970 UTC の最初の瞬間のエポックから (基本的に、詳細についてはクラス ドキュメントを参照してください)。ビジネス ロジック、データ ストレージ、およびデータ交換のほとんどは UTC で行う必要があるため、これは頻繁に使用する便利なクラスです。

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

OffsetDateTime

ここに画像の説明を入力してください

クラスOffsetDateTimeクラスは、UTCより何時間・分・秒進んでいるか遅れているかのコンテキストを持つ日付と時刻として瞬間を表します。オフセットの量、つまり何時間・分・秒の数は、ZoneOffsetクラス。

時間・分・秒の数がゼロの場合、OffsetDateTimeUTCの瞬間を表す。Instant

ZoneOffset

ここに画像の説明を入力してください

ZoneOffsetクラスはUTCからのオフセットUTC より進んでいる、または遅れている時間・分・秒数。

AZoneOffsetは単なる時間、分、秒の数値であり、それ以上のものではありません。ゾーンはそれ以上のものであり、名前とオフセットの変更履歴を持ちます。したがって、ゾーンを使用する方が、単なるオフセットを使用するよりも常に望ましいです。

ZoneId

ここに画像の説明を入力してください

タイムゾーンは、ZoneIdクラス。

新しい一日が早く明けるパリよりもモントリオール例えば、時計の針を動かして、よりよく反映させる必要があります。正午(太陽が真上にあるとき) 特定の地域におけるオフセット。西ヨーロッパ/アフリカの UTC ラインから東/西に離れるほど、オフセットは大きくなります。

タイムゾーンとは、地域社会や地域で実践されている調整や異常に対処するための一連のルールです。最も一般的な異常は、あまりにも一般的な狂気として知られているものです。夏時間 (DST)

タイムゾーンには、過去のルール、現在のルール、近い将来に確定するルールの履歴があります。

これらのルールは予想以上に頻繁に変更されます。日付時刻ライブラリのルールは必ず保存しておいてください。通常は「tz」データベース、最新の状態に保つ。OracleがリリースしたJava 8では、最新の状態を維持するのがこれまで以上に簡単になりました。タイムゾーン更新ツール

指定する適切なタイムゾーン名、、Continent/Regionまたはなどの の形式で使用します。や などの 2 ~ 4 文字の略語は、実際のタイムゾーンではなく、標準化されておらず、一意でもありません(!)ので、使用しないでください。America/MontrealAfrica/CasablancaPacific/AucklandESTIST

タイムゾーン = オフセット + 調整ルール

ZoneId z = ZoneId.of( “Africa/Tunis” ) ; 

ZonedDateTime

ここに画像の説明を入力してください

のことを考えるZonedDateTime概念的には、 がInstant割り当てられたとしてZoneId

ZonedDateTime = ( インスタント + ゾーン ID )

特定の地域 (タイムゾーン) の人々が使用する壁時計の時刻で現在の瞬間をキャプチャするには、次のようにします。

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 ) ;

2019年4月30日火曜日 23時22分55秒 インド

LocalDate、、LocalTimeLocalDateTime

LocalDate のカレンダーのみを示す図。

LocalTime の時計のみを示す図。

LocalDateTime のカレンダーと時計を示す図。

「ローカル」日付時刻クラス、LocalDateTimeLocalDateLocalTimeは、異なる種類の生き物です。 は、特定の地域や時間帯に縛られていません。 タイムラインにも縛られていません。タイムライン上のポイントを見つけるために地域に適用するまで、それらは実際の意味を持ちません

これらのクラス名にある「Local」という単語は、初心者には直感に反するかもしれません。この単語は、特定の地域ではなくあらゆる地域を意味します。

そのため、ビジネス アプリでは、「ローカル」型はあまり使用されません。これは、これらの型がタイムライン上の特定の瞬間ではなく、考えられる日付や時刻の一般的な概念を表すだけだからです。ビジネス アプリでは、請求書が届いたとき、製品が輸送のために出荷されたとき、従業員が雇用されたとき、タクシーがガレージを出発したときなどの正確な瞬間が重要になる傾向があります。そのため、ビジネス アプリの開発者は、クラスInstantZonedDateTimeクラスを最もよく使用します。

では、 はいつ使うのでしょうかLocalDateTime? 次の 3 つの状況で使います:

  • 特定の日付と時刻を複数の場所に適用したいと考えています。
  • 予約受付中です。
  • 予定されているが未確定のタイムゾーンがあります。

これら 3 つのケースはいずれもタイムライン上の特定の時点に関係しておらず、いずれも瞬間ではないことに注意してください。

一日のうちの1つの時間、複数の瞬間

特定の日付の特定の時刻を表現したいが、それを複数のタイムゾーンにまたがる複数の地域に適用したい場合があります。

たとえば、「クリスマスは2015年12月25日の真夜中に始まる」は、LocalDateTimeパリとモントリオールでは真夜中の時刻が異なり、またパリとモントリオールでは真夜中の時刻が異なります。シアトルそしてオークランド

LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
LocalTime lt = LocalTime.MIN ;   // 00:00:00
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;  // Christmas morning anywhere. 

別の例として、「Acme社では、世界中の各工場で昼食時間は午後12時30分に始まるという方針をとっています」は、 ですLocalTime。実際の意味を持たせるには、タイムラインに適用して、午後12時30分の瞬間を計算する必要があります。シュトゥットガルト工場または12:30ラバト工場または12:30シドニー工場。

予約

他にも、将来のイベントを予約する場合に使用できますLocalDateTime(例: 歯医者の予約)。これらの予約は、政治家がタイムゾーンを再定義するリスクがあるほど遠い将来の可能性があります。政治家は事前の警告をほとんど与えないか、まったく警告しないことがよくあります。政治家が時計をどう操作するかに関係なく、「来年の 1 月 23 日午後 3 時」を意味している場合は、瞬間を記録することはできません。たとえば、その地域で夏時間が導入されたり廃止されたりすると、午後 3 時が午後 2 時または午後 4 時に変わる可能性があります。

予定については、LocalDateTimeと を別々に保存します。後でスケジュールを生成するときに、 を呼び出してオブジェクトを生成する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クラスをより大きなコンテキストに配置するのに役立つ可能性があります。

Java (最新と旧式の両方) および SQL 標準のすべての日付/時刻型の表。

Java チームが JDBC 4.2 の設計で行った奇妙な選択に注目してください。彼らは、最もよく使用される 2 つのクラス ( & )を除いて、すべてのjava.time時間をサポートすることを選択しました。InstantZonedDateTime

でも心配はいりません。簡単に相互変換できます。

変換しています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.DateCalendar、&SimpleDateFormat

詳細については、Oracle チュートリアル. そして、Stack Overflowで多くの例と説明を検索してください。仕様はJSR310

ジョダタイムプロジェクト、現在メンテナンスモード、への移行を勧めているjava.timeクラス。

java.timeオブジェクトをデータベースと直接交換することができます。JDBC ドライバー準拠JDBC 4.2以降。文字列もクラスも不要ですjava.sql.*。Hibernate 5 と JPA 2.2 はjava.timeをサポートしています。

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

どのバージョンの Java または Android でどの java.time ライブラリを使用するかを示す表

スリーテンエクストラプロジェクトは、java.time に追加のクラスを追加して拡張します。このプロジェクトは、java.time に将来追加される可能性のある機能の実証の場です。ここでは、次のような便利なクラスが見つかるかもしれません。IntervalYearWeekYearQuarter、 そしてもっと

おすすめ記事