Java 8의 LocalDateTime에서 밀리 초를 얻는 방법


285

상기 새를 사용 1970년 1월 1일 (시대)부터 현재의 밀리 초를 얻을 수있는 방법이 있는지 궁금 LocalDate, LocalTime또는 LocalDateTime자바 8 클래스.

알려진 방법은 다음과 같습니다.

long currentMilliseconds = new Date().getTime();

또는

long currentMilliseconds = System.currentTimeMillis();

6
무슨 일이야 System.currentTimeMillis()?
Dawood ibn Kareem

16
@DavidWallace 그는 현재 시간이 아닌 날짜 시간을 얻으려고 노력하고 있습니까?
Anubian Noob

2
"... 현재 밀리 초를 얻는 방법 ..."
Dawood ibn Kareem

1-1-1970부터는 밀리 초입니다. Java 8 LocalDate, LocalTime 및 LocalDateTime의 새 클래스를 사용하여 가져올 수있는 방법이 있으면 방황하고 있었기 때문에 찾지 못했습니다.
George Siggouroglou

1
그 수업의 목적에 대한 나의 이해는 그것이 시간에 대한 "인간 중심의"이해이며, currentTimeMillis그 맥락과 관련이 없다는 것입니다. 캘린더와 벽시계를 정확한 정밀도로 생각하고 시간대와 지역에 대해 걱정하지 마십시오. 따라서 LocalTime에서 "UTC 시간"으로 돌아갈 수있는 방법이 없습니다
Gus

답변:


325

"현재 밀리 초"가 무엇을 의미하는지 완전히 확신 할 수는 없지만 1970 년 1 월 1 일 자정 (UTC) 이후 "에포크"이후의 밀리 초 수라고 가정하겠습니다.

당신은 시대 이후의 밀리 초 수를 찾으려면 지금 다음 사용 System.currentTimeMillis()으로 Anubian 멍청한 놈 지적했다 . 그렇다면 새로운 java.time API를 사용하여이를 수행 할 이유가 없습니다.

그러나 LocalDateTime어딘가에서 이미 비슷한 객체 가 있거나 신기원 이래로 밀리 초로 변환하려고합니다. LocalDateTime객체 계열에 시간대가 무엇인지에 대한 개념이 없기 때문에 직접 할 수 는 없습니다. 따라서 표준 시간대 정보는 UTC와 같은 신기원을 기준으로 시간을 찾기 위해 제공되어야합니다.

다음 LocalDateTime과 같은 것이 있다고 가정 하십시오.

LocalDateTime ldt = LocalDateTime.of(2014, 5, 29, 18, 41, 16);

시간대 정보를 적용하여을 제공해야합니다 ZonedDateTime. 저는 로스 앤젤레스와 같은 시간대에 있으므로 다음과 같은 작업을 수행합니다.

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Los_Angeles"));

물론 이것은 시간대에 대한 가정입니다. 예를 들어, 현지 시간으로 일광 절약 시간 (서머 타임) 전환 근처의 시간을 지정하는 경우와 같은 에지 사례가 발생할 수 있습니다. 이것들을 제쳐두고 보자. 그러나 당신은이 경우들이 존재한다는 것을 알아야한다.

어쨌든, 유효한을 얻을 수 있다면 ZonedDateTime, 에포크 이후로 밀리 초 수로 변환 할 수 있습니다.

long millis = zdt.toInstant().toEpochMilli();

5
참고 ZonedDateTime가 이미 가지고getEpochSecond (를 통해 방법을 ChronoZonedDateTime 기본 ). 필요 없습니다 Instant.
mabi

14
물론 필요한 것은 밀리 초가 아닌 초입니다.
스튜어트 마크

1
잘 아, 부정확했다 : ZonedDateTime또한이 InstantgetNano방법, 그래서 당신은 단지 대체 할 수 없을 것입니다 instzdt귀하의 예에?
mabi

18
zdt.get (ChronoField.MILLI_OF_SECOND)를 사용하여 나노에 대한 수학을 피하십시오. zdt.toInstant (). toEpochMilli ()를 사용하여 모든 수학을 피하십시오
JodaStephen

1
어쨌든, 당신과 @walen은 모두 주석을 달았으므로 오해의 소지가있는 사람들을 피하기 위해 지금 원래 메시지를 삭제하기로 결정했습니다.
Per Lundberg

81

시간대를 지정하지 않은 것은

System.out.println("ldt " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("ctm " + System.currentTimeMillis());

준다

ldt 1424812121078 
ctm 1424812121281

보시다시피 작은 실행 시간을 제외하고는 숫자가 동일합니다.

System.currentTimeMillis를 좋아하지 않는 경우를 대비하여 Instant.now().toEpochMilli()


3
아니요, Epoch는 UTC를 기준으로하지만 현재 시간은 현지 지역에서 가져옵니다.
Rafael Membrives

2
@ ChristofferHammarström 신기원 이래로 경과 한 시간 (밀리 초)은 사실상 시간대와 무관합니다. 어떤 시간에 전화하든 상관없이 동일한 밀리 초입니다. brian의 시스템이 두 번째 명령을 실행하는 데 203 밀리 초가 걸리기 때문에 두 결과가 다릅니다.
Fletch

사용자가 다른 시간대에있을 때 UTC를 사용해도
되나요?

2
@ GilbertS는 아마도이 정확한 코드를 사용해서는 안됩니다. 원하는대로 API를 사용하십시오. 컴퓨터에 저장하거나 다른 사용자에게 전송할 때 날짜 시간은 항상 UTC 여야합니다. 일반적으로 표준 시간대 설정을 사용하여 사용자에게 현지 날짜 시간으로 표시해야합니다.
브라이언

20

ZoneId를 피하려면 다음을 수행하십시오.

LocalDateTime date = LocalDateTime.of(1970, 1, 1, 0, 0);

System.out.println("Initial Epoch (TimeInMillis): " + date.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());

값으로 0을 얻는 것은 맞습니다!


8
ZoneOffset.ofTotalSeconds(0)그것은 동일합니다ZoneOffset.UTC
Anton Novopashin

1
예, @AntonNovopashin의 의견을 찬성했습니다. UTC가 필요했기 때문에 괜찮습니다 (답변에서 언급하고 싶을 수도 있습니다). BTW ZoneOffset는의 서브 클래스이므로 ZoneId, 피했다는 말은 아니지만, 행복하다면…
Ole VV

내 첫 번째 의견은 조금 가혹했지만 공격적이지 않았습니다. 당신은 공격했다. 미안 해요. 삭제했습니다. 다른 방법으로 물어 보도록하겠습니다. 피하고 ​​싶은 이유는 ZoneId무엇입니까?
Ole VV

@ OleV.V UTC를 사용해도 괜찮습니다. UTC 시간대에 사는 사람들만을위한 것이 아닙니다.
GilbertS

1
@ GilbertS 나는 누군가가 UTC 시간대에 살고 있다고 생각하지 않습니다. 시간대별로 사용되는 시간에 UTC를 사용하는 것이 좋습니다. 예를 들어 지리적으로 다양한 사용자를위한 날짜 조작 / 저장소에 대한 Java 모범 사례를 참조하십시오 . 아니면 당신의 질문을 이해하지 못했을까요?
Ole VV

15

Java 8부터을 호출 할 수 있습니다 java.time.Instant.toEpochMilli().

예를 들어 전화

final long currentTimeJava8 = Instant.now().toEpochMilli();

당신과 같은 결과를 제공합니다

final long currentTimeJava1 = System.currentTimeMillis();

1
"와 동일한 결과를 제공합니다."... 더 많은 CPU 전력을 소비하고 가비지 수집기에 더 많은 스트레스를줍니다.
VasiliNovikov

1
내가보고 싶은 정량화 위 (특히 정상적인 사용을위한 - 예를 들면되지 일부 성능 중요한 실시간 응용 프로그램 ...)
브라이언 애그뉴

11

java.sql.Timestamp밀리 초를 얻기 위해 사용할 수도 있습니다 .

LocalDateTime now = LocalDateTime.now();
long milliSeconds = Timestamp.valueOf(now).getTime();
System.out.println("MilliSeconds: "+milliSeconds);

시간대에 대한 중요한 요구를 무시하고 있습니다. 나는 이런 식으로하지 않는 것이 좋습니다. 또한 Timestamp클래스는 오래되어 오래된 디자인 문제로 가득 차 있으므로 특히 java.timelike 에서 클래스를 사용할 수있을 때 피하십시오 LocalDateTime.
Ole VV

@ OleV.V. 의 디자인 문제에 대해 궁금한 Timestamp점이 있습니다. 이에 대한 기사를 공유 할 수 있습니까? Timestamp내 코드에서도 사용하지 않아도됩니다. 감사!
Nalam

1
간단히 말해 하위 클래스로 구현 Date되지만 종종로 처리 할 수 ​​없습니다 Date. 상속 된 메소드 Date와 하나의 생성자가 대부분 사용되지 않습니다. 이 toString방법은 JVM의 시간대를 사용하는데, 이는 Timestamp다른 컴퓨터에서 다르게 인쇄 되기 때문에 많은 사람들을 혼동 합니다 ( :).
Ole VV

이것은 단위 테스트에 적합합니다. 그냥와 지금을 대체LocalDate.of(year, month, day)
G_V

"항상 UTC"값을 해결하기 위해 허용되는 답변이어야합니다.
LeYAUable

9

에포크 이후로 현재 시간을 밀리 초 단위로 얻으려면을 사용하십시오 System.currentTimeMillis().


3

Java 8 Clock을 사용하는 경우 사용할 수 있습니다 clock.millis()( clock.instant()보다 정확하기 때문에 Java 8 Instant를 얻는 것이 좋습니다 ).

왜 Java 8 시계를 사용 하시겠습니까? DI 프레임 워크에서 Clock bean을 생성 할 수 있습니다 :

@Bean
public Clock getClock() {
    return Clock.systemUTC();
}

그런 다음 테스트에서 쉽게 조롱 할 수 있습니다.

@MockBean private Clock clock;

또는 다른 콩을 가질 수 있습니다 :

@Bean
public Clock getClock() {
    return Clock.fixed(instant, zone);
}

날짜와 시간을 측정 할 수없는 테스트에 도움이됩니다.


1
  default LocalDateTime getDateFromLong(long timestamp) {
    try {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC);
    } catch (DateTimeException tdException) {
      //  throw new 
    }
}

default Long getLongFromDateTime(LocalDateTime dateTime) {
    return dateTime.atOffset(ZoneOffset.UTC).toInstant().toEpochMilli();
}

0

왜 사람은 방법을 언급 않았다 LocalDateTime.toEpochSecond():

LocalDateTime localDateTime = ... // whatever e.g. LocalDateTime.now()
long time2epoch = localDateTime.toEpochSecond(ZoneOffset.UTC);

이것은 많은 사람들이 위에서 제안한 답변보다 짧아 보입니다 ...


이것이 내가 찾던 것입니다. 그 대답은 저에게 유언장을주었습니다.
Brill Pappin

API 26에서만 사용 가능 : {
Brill Pappin

1
몇 초 밖에 걸리지 않기 때문입니다. toEpochMilliLocalDateTime에 나노초를 지정할 수 있다는 사실을 고려하여 메소드 가 없다는 것은 이상합니다 LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond). 메소드가 있습니다.
izogfif
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.