ミリ秒単位の長いエポック時間からJava 8 LocalDateを作成するにはどうすればよいですか?


218

longエポックの開始からのミリ秒で表されるs として日付を返す外部APIがあります。

古いスタイルのJava APIを使用すると、単純Date

Date myDate = new Date(startDateLong)

Java 8のLocalDate/ LocalDateTimeクラスに相当するものは何ですか?

私はによって表される時点を変換に興味を持っていますlongLocalDate、私の現在のローカルタイムゾーンで。


6
さて、あなたはあなたが気にしているタイムゾーンを決めることから始めなければなりません。「エポックからのミリ秒」の値は、瞬時を示します...異なるタイムゾーンの異なる日付を参照する可能性があります。それがjava.util.Dateそういう意味で実際に日付になることは決してなかったことを覚えておいてくださいLocalDate-それはまた、瞬間的なものでした。
Jon Skeet

2
:この質問をチェックstackoverflow.com/questions/21242110/...の変換をカバーjava.util.DateLocalDate
hotzst

3
注:このQ&Aは、File.lastModified()(エポックミリ)をに変換しようとするユーザーにも役立ちLocalDate(Time)ます。
kevinarpe 2017年

回答:


403

エポックからのミリ秒があり、現在のローカルタイムゾーンを使用してローカル日付に変換したい場合は、

LocalDate date =
    Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();

ただし、システムのデフォルトのタイムゾーンでさえも変化longする可能性があるため、同じマシン上であっても、同じ値を使用すると、その後の実行で異なる結果が生じる可能性があることに注意してください。

さらに、はLocalDate、とは異なりjava.util.Date、実際には日付と時刻ではなく日付を表すことに注意してください。

それ以外の場合は、次のものを使用できますLocalDateTime

LocalDateTime date =
    LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue), ZoneId.systemDefault());

2
詳細な説明については、+ 1してください。ちなみに、非システムゾーンでも(tzupdater-toolまたはjdk-changeによって)変更される可能性があるため、前後で異なる結果が生成されます。
Meno Hochschild、2016

2
@Meno Hochschild:私はハードコードされたタイムゾーンに焦点を合わせていませんでしたが、ユーザーが指定したタイムゾーンと比較して、構成ファイルまたは環境変数から読み取ります。ハードコードされたタイムゾーンは、実際にはシステムのデフォルトと非常によく似ています。プログラマーは、彼らが決して変わらないと思って誘惑されます…
Holger

2
@DemigodにLocalDateTime.ofEpochSecond(…)は実際のZoneOffsetが 必要ですが、をZoneId.systemDefault()返しますZoneIdZoneIdあなたが参照している時間のポイントに応じて、異なるオフセットにマッピングすることができます。それLocalDateTime.ofInstantはあなたのために何をするかです、ZoneId提供されたに従って指定されたを変換しますInstant
Holger

2
エポックはUTCとして定義されているため、タイムゾーンに依存しない必要があるため、ZoneIdは常にUTCである必要があります。
PlexQ

2
@PlexQ指定されたタイムゾーンは、実際にはタイムゾーンに依存しないエポックには関係ありませんが、結果のLocalDateまたはのセマンティクスには関係しLocalDateTimeます。これらの結果オブジェクトのその後の使用と一致している限り、任意のタイムゾーンを指定できます。さまざまなメソッドで作成された複数のオブジェクトを処理するとどうなるか考えてください。ローカル日付または日付時刻の一般的な使用例には、システムのデフォルトのタイムゾーンが組み込まれています。例:LocalDateTime.now()LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault())
Holger

37

Instant.ofEpochMilli(long)から開始できます。

LocalDate date =
  Instant.ofEpochMilli(startDateLong)
  .atZone(ZoneId.systemDefault())
  .toLocalDate();

5
タイムゾーンを明示するための+1。省略した場合、JVMの現在のデフォルトのタイムゾーンが日付の決定に暗黙的に適用されます。ある特定の瞬間において、新しい日が東の早い時期に始まるので、日付は世界中でタイムゾーンによって異なります。
バジルブルク

12

もっと良い答えがあると思います。

new Timestamp(longEpochTime).toLocalDateTime();

新しいTimestamp(ts).toLocalDateTime()。toLocalDate()
Stepan Yakovenko

5
つまり、javal.sql.Timestampをインポートすることを気にしない場合、Javaのモノリシックな性質を考えると、JVMの一部にすぎないので問題ないと思いますが、少し臭いがしますが、それはエポックが基本的にUTCにあると認識しました。
PlexQ

1
Timestampクラスは設計が不十分と長い時代遅れです。コードはJVMのタイムゾーン設定を使用しますが、この設定はプログラムの別の部分または同じJVMで実行されている別のプログラムによって変更される可能性があるため、それが何であるかはよくわかりません。
Ole VV

1
どのタイムゾーンが使用されているかを明示することは常に良いことです。古いjava.sql.Timestampを使用すると、システムのタイムゾーンが暗黙的に適用されるという欠点があり、通常は開発者の間で混乱を引き起こします。
ルスラン

3

タイムゾーンとスタッフはさておき、非常に単純な選択肢がするnew Date(startDateLong)かもしれませんLocalDate.ofEpochDay(startDateLong / 86400000L)


6
少なくとも86400000Lの意味を説明する必要があると思います。
BAERUS

3
1日のミリ秒数であることが簡単にわかると思いました。
Michael Piefel 2017年

7
一部の人にとってはそうであり、それだけが理にかなっていると思っていましたが、1日の実際のミリ秒数を再計算しなければ、確信が持てませんでした。自分のために言えば、私はこの数があまりよくわからないので、それが何を意味するのかを自動的に知っています。
BAERUS 2017年

受け入れられた答えが本当に最良の答えであることに注意してください、それはただ圧倒的に見えます。多くの場合、私の単純なハックで十分です。ジョーダのようにjava.time含まDateTimeConstantsれていないのは残念だ。
Michael Piefel 2017年

2
java.util.concurrent.TimeUnit.MILLISECONDS.toDays(startDateLong)
Vadzim

1

now.getTime()を長い値に置き換えます。

//GET UTC time for current date
        Date now= new Date();
        //LocalDateTime utcDateTimeForCurrentDateTime = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDateTime();
        LocalDate localDate = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDate();
        DateTimeFormatter dTF2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        System.out.println(" formats as " + dTF2.format(utcDateTimeForCurrentDateTime));

-6

エポック秒のタイムスタンプがSQLに由来するか、SQLに何らかの形で関連している特定のケースでは、次のように取得できます。

long startDateLong = <...>

LocalDate theDate = new java.sql.Date(startDateLong).toLocalDate();

2
これは、質問された質問とあまり関係がありません
Ketan R

@KetanR、同意しない。質問は「どのように得ることがあるLocalDateからepoch-millis」、と私は使用して、どのように表示さjava.sql.Date速記のために。このアプローチは、JDBCをある程度処理しているコードでは理にかなっており、問題なく機能します。それでも納得できない場合は、それが最初の質問に関係していないことを説明してください。
M.プロホロフ

2
質問を読むと、「日付をlongとして返す外部API」と表示されており、SQLから長い日付を受け取っている場合にこの変換を行う方法を説明しています。あなたの答えは日付変換の非常に具体的なケースを説明していますが、尋ねられた質問にはあまり関係がありません。
Ketan R

@ KetanR、SQLから長い日付を受け取った場合は、スキーマを変更して、そのような形式の日付を受信しないようにすることをお勧めします。ただし、日付を他の場所(外部API)からミリ秒のタイムスタンプとして受信し、これらの日付を使用してJDBCクエリを作成する場合、java.sql.Dateアプローチはコード内で利用可能な最短のものであり、それほど有用ではないと私は思いますしかし行くにInstant最終結果が同じであれば、すべての中間の一時的なオブジェクトと。
M.プロホロフ

2
私はすでに言ったように、あなたの最新の説明から明らかですが、あなたの答えは正解ですが、当面の質問には当てはまりません質問は次のように述べています。 "答えは次のとおりです:"ミリ秒のタイムスタンプとして日付を受け取り、すぐにこれらの日付を使用してJDBCクエリを作成します "。ここで何がはっきりしていないのかわかりません。
R
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.