LocalDateとLocalDateTimeからエポックを抽出する方法は?


102

またはのLongインスタンスからエポック値を抽出するにはどうすればLocalDateTimeよいLocalDateですか?私は以下を試しましたが、他の結果が得られます:

LocalDateTime time = LocalDateTime.parse("04.02.2014  19:51:01", DateTimeFormatter.ofPattern("dd.MM.yyyy  HH:mm:ss"));
System.out.println(time.getLong(ChronoField.SECOND_OF_DAY)); // gives 71461
System.out.println(time.getLong(ChronoField.EPOCH_DAY)); // gives 16105

私が欲しいのは、単に1391539861ローカルのdatetimeの値です"04.02.2014 19:51:01"。私のタイムゾーンはEurope/Oslo夏時間のUTC + 1です。


予想番号1396468261を説明してください。タイムゾーンを修正しないと、1391543461が表示されます(私の回答の編集を参照)。57日の違い!
Meno Hochschild、2014

@MenoHochschild質問をタイムゾーン情報で更新し、実際の値をGTMから現地時間に修正しました。LocalDateTime手動で計算するよりもエポックを取得する簡単な方法はありますか?

私の一時停止から戻ってきて、私の更新を参照してください。
Meno Hochschild、2014

回答:


147

クラスLocalDateLocalDateTimeは、タイムゾーンまたはタイムオフセットに関する情報、およびこの情報がなければエポックがあいまいになるための秒数は含まれません。ただし、オブジェクトには、ZoneIdインスタンスを渡すことにより、タイムゾーンを持つ日付/時刻オブジェクトに変換するいくつかのメソッドがあります。

LocalDate

LocalDate date = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = date.atStartOfDay(zoneId).toEpochSecond();

LocalDateTime

LocalDateTime time = ...;
ZoneId zoneId = ZoneId.systemDefault(); // or: ZoneId.of("Europe/Oslo");
long epoch = time.atZone(zoneId).toEpochSecond();

2
ZoneIdの使用を回避すること、またはカスタマイズされた一定のZoneIdインスタンス(+0の、GMTを意味する)で使用することは可能ですか?すべての計算をそれに正規化したいので、これを要求します。また、エポック時間からLocalDate / LocalDateTimeに変換します(これもZoneIdなし、またはGMT付き)。
android開発者

2
気にしないで。見つけた:ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0))
Android開発者

7
より単純なアプローチはlong epoch = time.toEpochSecond(ZoneOffset.UTC)、UTCの場合、またはタイムゾーンがすでにわかっている場合、またはlong epoch = time.toEpochSecond(ZoneId.systemDefault());そのルートを使用する場合のみです。
マーカス

これはばかげているように聞こえるかもしれませんが、エポックからLocalDate、LocalTime、LocalDateTimeに変換し直すのはどうですか
samuel owino

気にしたことはありません。 Instant.ofEpochMilli(responseTime).atZone(ZoneId.systemDefault()).toLocalTime()
samuel owino

27

「UNIXエポック以降のミリス」はインスタントを表すため、Instantクラスを使用する必要があります。

private long toEpochMilli(LocalDateTime localDateTime)
{
  return localDateTime.atZone(ZoneId.systemDefault())
    .toInstant().toEpochMilli();
}

ZoneId.systemDefault()UNIXエポックがUTCを参照しているため、使用するのは正しくありません
ACV

10

必要な変換には、UTC /グリーウィッチからのオフセット、またはタイムゾーンが必要です。

あなたはオフセットを持っている場合は、そこにある専用の方法LocalDateTimeこの作業のためには:

long epochSec = localDateTime.toEpochSecond(zoneOffset);

aしかない場合はZoneIdZoneOffsetから取得できますZoneId

ZoneOffset zoneOffset = ZoneId.of("Europe/Oslo").getRules().getOffset(ldt);

しかし、あなたはZonedDateTimeより簡単な変換を見つけるかもしれません:

long epochSec = ldt.atZone(zoneId).toEpochSecond();

4
あなたが唯一のUTCを気にした場合、そこにあるlong epochSec = localDateTime.toEpochSecond(ZoneOffset.UTC);
ruhong

2

見てください、この方法はサポートされているフィールドを参照してください。あなたは見つけるでしょうLocalDateTime

NANO_OF_SECOND 
NANO_OF_DAY 
MICRO_OF_SECOND 
MICRO_OF_DAY 
MILLI_OF_SECOND 
MILLI_OF_DAY 
SECOND_OF_MINUTE 
SECOND_OF_DAY 
MINUTE_OF_HOUR 
MINUTE_OF_DAY 
HOUR_OF_AMPM 
CLOCK_HOUR_OF_AMPM 
HOUR_OF_DAY 
CLOCK_HOUR_OF_DAY 
AMPM_OF_DAY 
DAY_OF_WEEK 
ALIGNED_DAY_OF_WEEK_IN_MONTH 
ALIGNED_DAY_OF_WEEK_IN_YEAR 
DAY_OF_MONTH 
DAY_OF_YEAR 
EPOCH_DAY 
ALIGNED_WEEK_OF_MONTH 
ALIGNED_WEEK_OF_YEAR 
MONTH_OF_YEAR 
PROLEPTIC_MONTH 
YEAR_OF_ERA 
YEAR 
ERA 

フィールドINSTANT_SECONDSは、もちろんですがLocalDateTime、絶対(グローバル)タイムスタンプを参照できないため、サポートされていません。しかし役立つのは、フィールド1970-01-01からの経過日数をカウントするEPOCH_DAYフィールドです。タイプについても同様の考えが有効ですLocalDate(サポートされるフィールドがさらに少なくなります)。

存在しないmillis-since-unix-epochフィールドを取得する場合は、ローカルタイプからグローバルタイプに変換するためのタイムゾーンも必要です。この変換ははるかに簡単に行うことができます。他のSO-postsを参照してください。

あなたの質問とあなたのコードの数字に戻ってください:

The result 1605 is correct
  => (2014 - 1970) * 365 + 11 (leap days) + 31 (in january 2014) + 3 (in february 2014)
The result 71461 is also correct => 19 * 3600 + 51 * 60 + 1

16105L * 86400 + 71461 = 1391543461 1970-01-01T00:00:00からの秒数(注意、タイムゾーンなし)次に、タイムゾーンオフセットを減算できます(ミリ秒単位の場合、1000による乗算の可能性に注意してください)。

指定されたタイムゾーン情報の後の更新:

local time = 1391543461 secs
offset = 3600 secs (Europe/Oslo, winter time in february)
utc = 1391543461 - 3600 = 1391539861

2つの同等のアプローチを持つJSR-310コードとして:

long secondsSinceUnixEpoch1 =
  LocalDateTime.of(2014, 2, 4, 19, 51, 1).atZone(ZoneId.of("Europe/Oslo")).toEpochSecond();

long secondsSinceUnixEpoch2 =
  LocalDate
    .of(2014, 2, 4)
    .atTime(19, 51, 1)
    .atZone(ZoneId.of("Europe/Oslo"))
    .toEpochSecond();

1
説明ありがとう。LocalDateTime time = LocalDateTime.parse("04.02.2014 19:51:01", DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"));次にを使用して正しい結果を得ましたLong epoch = time.atZone(ZoneId.of("Europe/Oslo")).toEpochSecond();

1

人間が読める日付からエポックに変換します

long epoch = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000;

エポックから人間が読める日付に変換します

String date = new java.text.SimpleDateFormat("MM/dd/yyyyHH:mm:ss").format(new java.util.Date (epoch*1000));

他の言語コンバーターの場合:https : //www.epochconverter.com


0

これは、時間帯を使用しない1つの方法です。

LocalDateTime now = LocalDateTime.now();
long epoch = (now.getLong(ChronoField.EPOCH_DAY) * 86400000) + now.getLong(ChronoField.MILLI_OF_DAY);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.