LocalDate 및 LocalDateTime에서 Epoch를 추출하는 방법은 무엇입니까?


102

또는 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입니다.


예상 번호 1396468261을 설명해주세요. 시간대 수정없이 도착합니다 : 1391543461 (내 답변의 편집 참조). 57 일 차이!
Meno Hochschild 2014

@MenoHochschild 시간대 정보로 질문을 업데이트하고 GTM의 실제 값을 현지 시간으로 수정했습니다. LocalDateTime수동으로 계산하는 것보다 다른 시대를 얻는 더 쉬운 방법 이 있습니까?

내 일시 중지에서 돌아 오면 내 업데이트를 참조하십시오.
Meno Hochschild 2014

답변:


147

클래스 LocalDateLocalDateTime에 대한 정보는 포함하지 않는 시간대 또는 오프셋 시간을 시대 이후, 초는이 정보가없는 ambigious 될 것이다. 그러나 객체에는 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 의미)와 함께 사용할 수 있습니까? 나는 모든 계산이 정규화되기를 원하기 때문에 이것을 묻습니다. 또한 어떻게 반대로 할 수 있습니까? epoch 시간에서 LocalDate / LocalDateTime으로 변환 (ZoneId없이 또는 GMT 사용)?
안드로이드 개발자

2
신경 쓰지 마. 발견 :ZoneId.ofOffset("UTC", ZoneOffset.ofHours(0))
안드로이드 개발자

7
더 간단한 접근 방식은 long epoch = time.toEpochSecond(ZoneOffset.UTC)UTC의 경우 또는 이미 시간대를 알고 있거나 long epoch = time.toEpochSecond(ZoneId.systemDefault());해당 경로로 이동하려는 경우입니다.
Marcus

우스꽝스럽게 들릴지 모르지만 epoch에서 LocalDate, LocalTime 및 LocalDateTime으로 다시 변환하는 것은 어떻
습니까

내가 찾은 것 같아 신경 쓰지 마세요. Instant.ofEpochMilli(responseTime).atZone(ZoneId.systemDefault()).toLocalTime()
samuel owino

27

'Millis since unix epoch'는 순간을 나타내므로 Instant 클래스를 사용해야합니다.

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

ZoneId.systemDefault()유닉스 신기원이 UTC
ACV

10

필요한 변환에는 UTC / Greewich의 오프셋 또는 시간대가 필요합니다.

오프셋이있는 경우이 작업 에 대한 전용 방법LocalDateTime 이 있습니다.

long epochSec = localDateTime.toEpochSecond(zoneOffset);

a 만 있으면 ZoneId다음 ZoneOffset에서 얻을 수 있습니다 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 = 1970-01-01T00 : 00 : 00 이후 1391543461 초 (주의, 시간대 없음) 그런 다음 시간대 오프셋을 뺄 수 있습니다 (밀리 초 단위 인 경우 1000 배의 가능한 곱셈에주의).

주어진 시간대 정보 이후 업데이트 :

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

두 개의 동등한 접근 방식을 사용하는 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

사람이 읽을 수있는 날짜에서 epoch로 변환 :

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

이것은 시간대를 사용하지 않는 한 가지 방법입니다.

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.