밀리 초 단위로 긴 Epoch 시간에서 Java 8 LocalDate를 작성하려면 어떻게해야합니까?


218

longEpoch가 시작된 이후 밀리 초로 표시되는 날짜를 s 로 반환하는 외부 API가 있습니다.

이전 스타일의 자바 API로, 나는 간단하게 만들 것 Date와의를

Date myDate = new Date(startDateLong)

Java 8 LocalDateLocalDateTime클래스 의 해당 내용은 무엇입니까 ?

나는에 의해 표현 시점 변환에 관심이 longA를 LocalDate내 현재 로컬 시간대에.


6
당신은 당신이 관심있는 시간대를 운동으로 시작해야합니다. "에포크 이후 밀리 초"값은 다른 시간대의 다른 날짜를 참조 할 수있는 시간을 즉각적으로 제공합니다. 그것이 java.util.Date실제로 날짜와는 거리가 멀다는 것을 명심하십시오 LocalDate.
Jon Skeet

2
:이 질문에 확인 stackoverflow.com/questions/21242110/... 의 변환을 커버 java.util.DateLocalDate
hotzst

3
참고 :이 Q & A는 File.lastModified()(epoch millis)을 ( 를)로 변환하려는 사용자에게도 유용 합니다 LocalDate(Time).
kevinarpe

답변:


403

Epoch 이후 밀리 초가 있고 현재 현지 시간대를 사용하여 현지 날짜로 변환하려면 다음을 사용할 수 있습니다.

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

2
@Meno Hochschild : 하드 코딩 된 시간대에 중점을 두지 않고 프로그래머가 자연스럽게 변경 될 수 있다고 가정하는 환경 파일 또는 환경 변수에서 읽은 사용자가 지정한 시간대와 비교했습니다. 하드 코딩 된 시간대는 실제로 시스템 기본값과 매우 유사합니다. 프로그래머는 결코 변하지 않을 것이라고 생각하고 유혹을
Holger

2
@Demigod은 LocalDateTime.ofEpochSecond(…)실제를 필요로 ZoneOffset하지만, ZoneId.systemDefault()을 반환합니다 ZoneId. A는 ZoneId당신이 참조하고 시점에 따라 다른 오프셋에 매핑 할 수 있습니다. 즉 무엇 LocalDateTime.ofInstant지정된 변환, 당신을 위해 수행 ZoneId제공된에 따라 Instant.
Holger

2
Epoch는 UTC로 정의되므로 시간대와 독립적이어야하므로 ZoneId는 항상 UTC 여야합니다.
PlexQ

2
@PlexQ 지정된 시간대는 실제로 시간대와 무관 한 Epoch와 관련이 없지만 결과 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의 현재 기본 시간대가 내재적으로 적용됩니다. 주어진 순간마다 날짜가 동부에서 일찍 새벽이되면서 시간대에 따라 날짜가 다릅니다.
Basil Bourque

12

더 나은 대답이 있다고 생각합니다.

new Timestamp(longEpochTime).toLocalDateTime();

새로운 타임 스탬프 (TS) .toLocalDateTime () toLocalDate ().
스테판 Yakovenko 보낸

5
내 말은-Java의 모 놀리 식 특성을 고려할 때 javal.sql.Timestamp를 가져 오는 것이 마음에 들지 않으면 JVM의 모든 부분이기 때문에 괜찮다고 생각하지만 약간 냄새가 있지만 여전히 더 좋아집니다. 신기원은 기본적으로 UTC입니다.
PlexQ

1
Timestamp클래스는 잘못 설계 및 긴 구식입니다. 코드는 JVM의 시간대 설정을 사용하지만이 설정은 프로그램의 다른 부분이나 동일한 JVM에서 실행중인 다른 프로그램에 의해 변경 될 수 있으므로 그 설정이 무엇인지 확실하지 않습니다.
Ole VV

1
어떤 시간대가 사용되는지 명시 적으로 나타내는 것이 좋습니다. 이전 java.sql.Timestamp를 사용하면 시스템 시간대가 내재적으로 적용되는 단점이 있으며 이는 일반적으로 개발자들 사이에 혼란을 야기합니다.
Ruslan

3

시간대와 물건을 제쳐두고 아주 간단한 대안이 new Date(startDateLong)될 수 있습니다.LocalDate.ofEpochDay(startDateLong / 86400000L)


6
적어도 86400000L의 의미를 설명해야한다고 생각합니다.
BAERUS

3
나는 하루에 밀리 초의 수를 알아내는 것이 매우 쉽다고 생각했습니다.
Michael Piefel 2018 년

7
어떤 사람들에게는 그것이 의미가 있다고 생각했지만, 하루에 실제로 얼마나 많은 ms를 재 계산하지 않으면 확실하지 않습니다. 나 자신을 위해 말하면, 나는이 숫자를 잘 몰라서 그것이 무엇을 의미하는지 자동으로 알 수 있습니다.
BAERUS

또한 허용되는 답변은 실제로 가장 좋은 답변이며 압도적입니다. 내 간단한 해킹은 많은 경우에 충분합니다. Joda가 java.time포함하지 않은 것은 유감입니다 DateTimeConstants.
Michael Piefel 2016 년

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. Prokhorov 2014

2
질문을 읽으면 "날짜를 오래 반환하는 외부 API"라고 표시되며 SQL에서 긴 날짜를 수신하면이 변환을 수행하는 방법을 설명합니다. 귀하의 답변은 날짜 변환의 매우 구체적인 사례를 설명하지만 실제로 질문 된 질문과 관련이 없습니다. 귀하의 설명은 다른 관련 질문에 대한 올바른 답변 일 수 있습니다.
Ketan R

@KetanR, SQL에서 긴 날짜를 받으면 더 이상 그러한 형식의 날짜를받지 않도록 스키마를 변경하는 것이 좋습니다. 그러나 다른 곳에서 날짜를 밀리 타임 스탬프로 수신하고 (외부 API) 즉시이 날짜를 사용하여 JDBC 쿼리를 작성하면 java.sql.Date접근 방식이 코드 방식으로 가장 짧으며 접근 방식이 유용하지는 않습니다. Instant최종 결과가 같을 때 모든 중간 시간 객체와 함께 가야 합니다.
M. Prokhorov 2014

2
내가 이미 말하고 최근의 설명에서 분명한 것처럼, 귀하의 대답은 정확하지만 당면한 질문에 대해서는 아닙니다. "귀하의 답변은"날짜를 밀리 타임 스탬프로 받고 즉시이 날짜를 사용하여 JDBC 쿼리를 만듭니다 "라고 말합니다. 나는 여기서 명확하지 않은 것을 이해하지 못합니까?
Ketan R
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.