web-dev-qa-db-ja.com

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

そんなこと知ってる:

  • インスタントは、計算用の「技術的な」タイムスタンプ表現(ナノ秒)です。
  • LocalDateTimeは、人間のタイムゾーンを含む日付/クロック表現です。

まだ結局のところ、IMOは両方ともほとんどのアプリケーションユースケースのタイプとして捉えることができます。例:現在、日付に基づいて次の実行を計算する必要があるバッチジョブを実行しています。これら2つのタイプ間の長所/短所を見つけるのに苦労していますLocalDateTime).

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

編集:精度と時間帯に関するLocalDateTimeの誤読された文書化に注意してください

172
manuel aldana

Table of types of date-time class in modern Java.time versus legacy.

tl; dr

Instantname__とLocalDateTimename__は、まったく異なる2つの動物です。1つは瞬間を表し、もう1つはそうではありません。

  • Instantname__はモーメント、タイムライン内の特定の時点を表します。
  • LocalDateTimename__は日付と時刻を表します。しかし、タイムゾーンやUTCからのオフセットがない、このクラスはできません瞬間を表すことはできません。これは、約26から27時間の範囲のpotentialmomentを表します。これは、世界中のすべてのタイムゾーンの範囲です。

誤った推定

LocalDateTimename__は、人間のタイムゾーンを含む日付/クロック表現です。

あなたの文は正しくありません:A LocalDateTimeNAME _ hasnotime zone。タイムゾーンがないということは、そのクラスのすべてのポイントです。

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

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

そのためLocal…は「ゾーンなし」を意味します。

Instantname__

enter image description here

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

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

OffsetDateTimename__

クラス OffsetDateTimeNAME _ クラスは、UTCの前後数時間 - 分 - 秒のコンテキストで、日時を時刻として表します。この番号はZoneOffsetname__クラスで表されます。

時 - 分 - 秒の数がゼロの場合、OffsetDateTimename__は、UTCでのInstantname__と同じモーメントを表します。

ZoneOffsetname__

ZoneOffsetNAME _ クラスは、 TCからのオフセット (UTCより前またはUTCより後の時間数分秒)を表します。

ZoneOffsetname__は単なる数値であり、タイムゾーン(ZoneIdname__)には変更の名前と履歴はありません。そのため、ゾーンを使用することは、単なるオフセットを使用することよりも常に望ましい方法です。

ZoneIdname__

enter image description here

A ZoneIdNAME _タイムゾーン です。

タイムゾーンは、UTCから何時間も何分も離れたオフセットと、それ以上の情報です。たとえば、 モントリオール よりも パリ の方が早い日が始まります。ですから、私たちは時計の針を動かして、与えられた地域の 正午 (太陽が真上にあるとき)をよりよく反映する必要があります。西ヨーロッパ/アフリカのUTC線から東/西に離れるほどオフセットが大きくなります。

さらに、タイムゾーンは、地域のコミュニティまたは地域で実施されている調整や異常を処理するための一連の規則です。最も一般的な異常は、 Daylight Saving Time(DST) として知られる、あまりにも一般的な狂気です。

タイムゾーンには、過去の規則、現在の規則、および近い将来に確認された規則の履歴があります。

これらの規則は、予想以上に頻繁に変更されます。日時ライブラリの規則、通常は 'tz'データベース のコピーを常に最新の状態に保ってください。 Java 8では、 Timezone Updater Tool がリリースされ、最新の状態に保つことがこれまでになく簡単になりました。

Continent/RegionAmerica/MontrealAfrica/Casablancaのように、 正しいタイムゾーン名Pacific/Aucklandの形式で指定します。 ESTname__やISTname__のような2文字から4文字の略語は、not真のタイムゾーンであり、標準化されておらず、一意でもないので絶対に使用しないでください。

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

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

ZonedDateTimename__

enter image description here

ZonedDateTimeNAME _ は、概念的にはInstantname__が割り当てられたZoneIdname__と考えてください。

ZonedDateTime =(Instant + ZoneId)

特定の地域(時間帯)の人々によって使用される壁時計の時間に見られるように現在の瞬間をキャプチャするために:

ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`. 

バックエンド、データベース、ビジネスロジック、データの永続化、データ交換のほぼすべてがUTCで行われるはずです。しかし、ユーザーに提示するには、ユーザーが期待するタイムゾーンに調整する必要があります。これがZonedDateTimename__クラスと、これらの日時値のストリング表現を生成するために使用される フォーマッタークラス の目的です。

ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ;                 // Standard ISO 8601 format.

DateTimeFormatterNAME _ を使用して、ローカライズされた形式でテキストを生成できます。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ; 
String outputFormatted = zdt.format( f ) ;

マルディ30 4月2019から23時間22分55秒

LocalDatename__、LocalTimename__、LocalDateTimename__

Diagram showing only a calendar for a <code>LocalDate</code>.

Diagram showing only a clock for a <code>LocalTime</code>.

Diagram showing a calendar plus clock for a <code>LocalDateTime</code>.

"ローカル"日時クラス、 LocalDateTimeNAME _LocalDateNAME _LocalTimeNAME _ は、異なる種類のクリッターです。地域やタイムゾーンに関連付けられていません。それらはタイムラインに結び付けられていません。 本当の意味はありませんタイムライン上のポイントを見つけるために地域に適用するまで==。

たとえば、「クリスマスは2015年12月25日の真夜中に始まります」はLocalDateTimename__です。真夜中はパリのモントリオールとは異なる瞬間に攻撃し、 シアトルオークランド でもまた違ったものになります。

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 PMに開始するという方針をとっています」というLocalTimename__です。本当の意味を持つためには、 Stuttgart factoryで12:30、または Rabat factoryまたは12:30で12:30の瞬間を計算するためにタイムラインにそれを適用する必要があります。 シドニー 工場で。

これらのクラス名の中の「Local」という単語は、初心者にとって直観的ではないかもしれません。 Wordはanylocality、またはeverylocalityを意味しますが、not特定の地域.

そのため、ビジネスアプリの場合、「ローカル」タイプは、タイムライン上の特定の瞬間ではなく、可能な日付または時間の一般的な概念を表すため、あまり使用されません。ビジネスアプリケーションは、請求書が到着した瞬間、輸送のために出荷された製品、従業員が雇われた、またはタクシーがガレージを出た正確な瞬間を気にする傾向があります。そのため、ビジネスアプリ開発者はInstantname__とZonedDateTimename__をほぼ排他的に使用します。

予約の予約

その一方で、将来のイベントの予約にはLocal…タイプを使用する必要があります(例:歯科医の予約)。政治家が頻繁に行うようにほとんど事前の警告なしにタイムゾーンを再定義する危険があります。

予定の場合は、LocalDateTimename__をZoneIdname__とともに格納します。後で、スケジュールを生成するときに、LocalDateTime::atZone( ZoneId )を呼び出してZonedDateTimename__オブジェクトを生成することによって、その場でオンザフライで決定します。

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に調整することができます。 Instantname__からZonedDateTimename__を抽出します。

Instant instant = zdt.toInstant() ;  // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock time.

すべての日時タイプ

完全を期すために、ここに、Javaにおける現代とレガシーの両方の可能なすべての日時タイプ、およびSQL規格で定義されているものの表を示します。これはInstantname__とLocalDateTimename__クラスをより大きなコンテキストに配置するのに役立つかもしれません。

Table of all date-time types in Java (both modern & legacy) as well as SQL standard.

JDBC 4.2の設計においてJavaチームによって行われた奇妙な選択に注目してください。彼らはすべてのJava.time回をサポートすることを選びました…もっともよく使われる2つのクラスInstantname__とZonedDateTimename__を除く。

でも心配しないで。簡単に前後に変換できます。

Instantname__を変換しています。

// Storing
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;

// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;

ZonedDateTimename__を変換しています。

// 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.DateCalendarNAME _ 、& SimpleDateFormatNAME _ のような、厄介な レガシー 日時クラスに代わるものです。

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

詳細は、 Oracleチュートリアル を参照してください。そして多くの例と説明についてはStack Overflowを検索してください。指定は JSR 31 です。

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

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

  • Java SE 8Java SE 9Java SE 1 、およびそれ以降
    • ビルトイン。
    • バンドル実装の標準Java APIの一部。
    • Java 9では、いくつかのマイナーな機能と修正が追加されています。
  • Java SE 6 および Java SE 7
    • Java.time機能の多くは ThreeTen-Backport でJava 6と7にバックポートされています。
  • Android
    • Java.timeクラスのAndroidバンドル実装の最新バージョン。
    • 初期のAndroid(<26)では、 ThreeTenABP プロジェクトが適応していますThreeTen -Backport(前述)。 ThreeTenABPの使い方… を参照してください。

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

487
Basil Bourque

主な違いの1つは、LocalLocalDateTime部分です。あなたがドイツに住んでいてLocalDateTimeインスタンスを作成し、他の誰かがアメリカに住んでいて(クロックが適切に設定されていれば)別のインスタンスを作成する場合 - これらのオブジェクトの値は実際には異なります。これはタイムゾーンとは無関係に計算されるInstantには適用されません。

LocalDateTimeは、タイムゾーンなしで日付と時刻を格納しますが、初期値はタイムゾーンに依存します。 Instantは違います。

さらに、LocalDateTimeは、days、hours、monthsなどの日付コンポーネントを操作するためのメソッドを提供します。 Instantはそうではありません。

instantのナノ秒単位の精度の利点とLocalDateTimeのタイムゾーン部分は別として

両方のクラスは同じ精度を持ちます。 LocalDateTimeはタイムゾーンを格納しません。 javadocを徹底的に読んでください。このような無効な仮定には間違いをするかもしれません。 Instant および LocalDateTime です。

18
Dariusz

あなたは間違っています LocalDateTime :それはタイムゾーン情報を全く格納せず、そしてそれはナノ秒の精度を持ちます。 Javadocを引用する(私のことを強調する)

ISO-8601カレンダーシステムでタイムゾーンなしの日時、2007-12-03T10:15:30など。

LocalDateTimeは日時を表す不変の日時オブジェクトです。年月日日時時分秒として表示されることがよくあります。年、日、曜日など、他の日付と時刻のフィールドにもアクセスできます。 時間はナノ秒の精度で表されます。たとえば、値 "2007年10月2日13:45.30.123456789"は、LocalDateTimeに格納できます。

この2つの違いは、 Instant はエポック(01-01-1970)からのオフセットを表し、したがってタイムライン上の特定の瞬間を表すということです。地球の2つの異なる場所で同時に作成された2つのInstantオブジェクトは、まったく同じ値を持ちます。

10
Tunaki

Instantは、主子午線(グリニッジ)の時間に対応しています。

これに対し、 LocalDateTime OSのタイムゾーン設定に関連します。

オフセットやタイムゾーンなどの追加情報がないと、瞬間を表すことはできません。

1
user2418306