web-dev-qa-db-ja.com

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

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の値"04.02.2014 19:51:01"です。私のタイムゾーンはEurope/Oslo UTC + 1で夏時間です。

77
user1019830

クラスLocalDateおよびLocalDateTimeには、timezoneまたはtime offsetに関する情報が含まれていません、およびこの情報がないとエポックがあいまいになるための秒数。ただし、オブジェクトには、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();
115
nosid

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

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

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

オフセットがある場合、このタスクにはLocalDateTime専用メソッド があります。

long epochSec = localDateTime.toEpochSecond(zoneOffset);

ZoneIdしかない場合は、ZoneOffsetからZoneIdを取得できます。

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

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

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

このメソッド を見て、サポートされているフィールドを確認してください。 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 

LocalDateTimeは絶対(グローバル)タイムスタンプを参照できないため、INSTANT_SECONDSフィールドは-もちろん-サポートされていません。しかし、役に立つのはフィールド Epoch_DAY です。これは1970-01-01からの経過日数をカウントします。タイプ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 = 1970-01-01T00:00:00から1391543461秒(注意、タイムゾーンなし)その後、タイムゾーンオフセットを減算できます(ミリ秒単位の場合、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
Meno Hochschild

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

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

Epochから人間が読める日付に変換

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

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

0
michmich