127

Longまたはのインスタンスからエポック値を抽出するにはどうすればよいですLocalDateTimeLocalDate? 次のことを試しましたが、他の結果が得られます。

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 です。

4

6 に答える 6

179

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

ローカル日付

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();
于 2014-04-10T15:36:42.110 に答える
33

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

private long toEpochMilli(LocalDateTime localDateTime)
{
  return localDateTime.atZone(ZoneId.systemDefault())
    .toInstant().toEpochMilli();
}
于 2016-11-21T11:20:19.787 に答える
11

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

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

long epochSec = localDateTime.toEpochSecond(zoneOffset);

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

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

ZonedDateTimeしかし、より簡単な方法で変換を見つけることができます:

long epochSec = ldt.atZone(zoneId).toEpochSecond();
于 2014-04-11T14:38:39.980 に答える
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 は、もちろんサポートされていません。これは、 aLocalDateTimeが絶対 (グローバル) タイムスタンプを参照できないためです。しかし、役立つのは、1970 年 1 月 1 日からの経過日数をカウントするフィールド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 = 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();
于 2014-04-10T14:09:32.750 に答える