Instant와 LocalDateTime의 차이점은 무엇입니까?


255

나는 그것을 알고있다 :

  • Instant 는 컴퓨팅을위한 "기술적 인"타임 스탬프 표현 (나노초)입니다.
  • LocalDateTime 은 사람을위한 시간대를 포함한 날짜 / 시계입니다.

여전히 최종 IMO에서는 대부분의 응용 프로그램 사용 사례의 유형으로 사용할 수 있습니다. 예 : 현재 날짜를 기준으로 다음 실행을 계산 해야하는 배치 작업을 실행 중이며 Instant와 시간대 부분의 나노 초 정밀도 이점을 제외 하고는이 두 유형 사이의 장단점을 찾는 데 어려움을 겪고 있습니다. LocalDateTime).

Instant 또는 LocalDateTime 만 사용해야하는 일부 응용 프로그램의 이름을 지정할 수 있습니까?

편집 : 정밀도 및 시간대와 관련하여 LocalDateTime에 대한 잘못된 문서를주의하십시오


인스턴트는 UTC의 표준 길이를 감싸는 기본 요소입니다. 배치와 같은 크론의 경우 그렇게 논리적 인 선택은 아닙니다.
Joop Eggen

37
잘못된 정의입니다. 시간대 LocalDateTime없습니다 !
Basil Bourque

답변:


828

최신 및 기존 Java의 모든 날짜-시간 유형 표

tl; dr

Instant그리고 LocalDateTime두 개의 완전히 다른 동물이다 : 하나는 순간을 나타내고, 다른 하나는하지 않습니다.

  • Instant 타임 라인의 특정 지점 인 순간을 나타냅니다.
  • LocalDateTime날짜와 시간을 나타냅니다. 그러나 표준 시간대 나 UTC에서 오프셋 없으면 이 클래스 순간을 나타낼 수 없습니다 . 전 세계 모든 시간대의 약 26-27 시간 범위의 잠재적 모멘트를 나타냅니다 .

잘못된 추정

LocalDateTime 인간을위한 시간대를 포함하여 오히려 날짜 / 시계 표현입니다.

귀하의 진술이 잘못되었습니다 : A 표준 시간대 LocalDateTime없습니다 . 시간대가없는 것이 그 수업의 핵심입니다.

해당 클래스의 문서를 인용하려면 :

이 클래스는 시간대를 저장하거나 나타내지 않습니다. 대신, 생일에 사용되는 벽시계에서 볼 수있는 현지 시간과 함께 날짜에 대한 설명입니다. 오프셋 또는 시간대와 같은 추가 정보가 없으면 타임 라인에서 순간을 나타낼 수 없습니다.

따라서 Local…"구역화되지 않음, 오프셋 없음"을 의미합니다.

Instant

여기에 이미지 설명을 입력하십시오

Instant의 타임 라인에 순간 UTC 의 카운트 나노초 1970 UTC (기본적으로, 핵심적 견실 한 세부 사항에 대한 클래스 문서를 참조)의 첫 순간의 시대입니다. 대부분의 비즈니스 로직, 데이터 스토리지 및 데이터 교환은 UTC로 이루어져야하므로 자주 사용하는 편리한 클래스입니다.

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

OffsetDateTime

여기에 이미지 설명을 입력하십시오

클래스 OffsetDateTime클래스는 UTC보다 앞 또는 뒤에서 몇 분 분 단위의 컨텍스트로 날짜와 시간으로 순간을 나타냅니다. 시간 분-초 수인 오프셋의 양은 ZoneOffset클래스 로 표시됩니다 .

시간-분-초 수가 0 인 경우 OffsetDateTime는 UTC와 모멘트를 나타냅니다 Instant.

ZoneOffset

여기에 이미지 설명을 입력하십시오

ZoneOffset클래스는 UTC 보다 앞뒤 또는 UTC보다 몇 분-초 단위의 UTC 에서 오프셋을 나타냅니다 .

A ZoneOffset는 단지 몇 시간 분만에 지나지 않습니다. 이름과 오프셋 변경 내역이있는 영역이 훨씬 더 많습니다. 따라서 단순한 오프셋을 사용하는 것보다 항상 영역을 사용하는 것이 좋습니다.

ZoneId

여기에 이미지 설명을 입력하십시오

시간대 에 의해 표현되는 ZoneId클래스입니다.

예를 들어 몬트리올 보다 파리 에서 새로운 하루 가 시작됩니다 . 따라서 주어진 지역에 대해 정오 (태양이 바로 오버 헤드 인 경우) 를 더 잘 반영하려면 시계 바늘을 움직여야합니다 . 서유럽 / 아프리카의 UTC 라인에서 동쪽 / 서쪽으로 멀수록 오프셋이 더 커집니다.

표준 시간대는 지역 사회 또는 지역에서 시행하는 조정 및 예외 사항을 처리하기위한 일련의 규칙입니다. 가장 일반적인 예외는 일광 절약 시간 (DST) 으로 알려진 너무나 대중적인 미치 입니다.

시간대에는 과거 규칙, 현재 규칙 및 가까운 미래에 대해 확인 된 규칙의 기록이 있습니다.

이러한 규칙은 예상보다 자주 변경됩니다. 날짜-시간 라이브러리의 규칙, 일반적으로 'tz'데이터베이스 사본을 최신 상태로 유지하십시오 . Java가 Timezone Updater Tool을 출시함으로써 Java 8에서 최신 상태를 유지하는 것이 그 어느 때보 다 쉬워졌습니다 .

지정 적절한 시간대 이름 의 형식 Continent/Region예컨대, America/Montreal, Africa/Casablanca, 또는 Pacific/Auckland. 표준 시간대 가 아니EST 거나 표준화되지 않았으며 고유하지 않은IST 것과 같은 2-4 자의 약어를 사용하지 마십시오 .

시간대 = 오프셋 + 조정 규칙

ZoneId z = ZoneId.of( Africa/Tunis ) ; 

ZonedDateTime

여기에 이미지 설명을 입력하십시오

ZonedDateTime개념적으로 Instant할당 된 으로 생각하십시오 ZoneId.

ZonedDateTime = (인스턴트 + ZoneId)

특정 지역 (시간대)의 사람들이 사용하는 벽시계 시간에서 볼 수있는 현재 순간을 포착하려면 :

ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`. 

거의 모든 백엔드, 데이터베이스, 비즈니스 로직, 데이터 지속성, 데이터 교환은 모두 UTC로 이루어져야합니다. 그러나 사용자에게 프리젠 테이션하려면 사용자가 예상 한 시간대로 조정해야합니다. 이것은 ZonedDateTime클래스와 그 날짜-시간 값의 문자열 표현을 생성하는 데 사용되는 포맷터 클래스 의 목적입니다 .

ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ;                 // Standard ISO 8601 format.

을 사용하여 현지화 된 형식으로 텍스트를 생성 할 수 있습니다 DateTimeFormatter.

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ; 
String outputFormatted = zdt.format( f ) ;

mardi 30 avril 2019 à 23 시간 22 분 55 s heure de l' Inde

LocalDate, LocalTime,LocalDateTime

<code> LocalDate </ code>의 달력 만 표시하는 다이어그램.

<code> LocalTime </ code>의 시계 만 보여주는 다이어그램.

<code> LocalDateTime </ code>의 달력과 시계를 보여주는 다이어그램.

"로컬"날짜 시간 클래스는, LocalDateTime, LocalDate, LocalTime, 생물의 다른 종류입니다. 지역이나 시간대와 관련이 없습니다. 타임 라인에 묶여 있지 않습니다. 타임 라인에서 요점을 찾기 위해 지역에 적용하기 전까지 는 의미가 없습니다 .

이 클래스 이름에서 "로컬"이라는 단어는 시작하지 않은 사람에게는 반 직관적 일 수 있습니다. 단어는 모든 지역 또는 모든 지역을 의미 하지만 특정 지역은 아닙니다 .

따라서 비즈니스 앱의 경우 "로컬"유형은 타임 라인의 특정 시점이 아닌 가능한 날짜 또는 시간에 대한 일반적인 아이디어를 나타 내기 때문에 자주 사용되지 않습니다. 비즈니스 앱은 송장이 도착한 순간, 운송을 위해 선적 된 제품, 직원을 고용했거나 택시가 차고를 떠난 순간을 중요하게 생각합니다. 비즈니스 응용 프로그램 개발자의 사용 그래서 InstantZonedDateTime가장 일반적으로 클래스.

그럼 언제 사용 LocalDateTime할까요? 세 가지 상황 : 여러 위치에 특정 날짜 및 시간을 적용하려는 경우, 약속을 예약하는 경우 또는 아직 결정되지 않은 표준 시간대가있는 경우. 이 세 가지 사례 중 어느 것도 타임 라인의 특정 특정 지점이 아니며 순간도 아닙니다.

하루에 한 번, 여러 순간

때로는 특정 날짜의 특정 시간을 나타내려고하지만 시간대 전체의 여러 지역에 적용하려고합니다.

예를 들어 "크리스마스는 2015 년 12 월 25 일 자정에 시작합니다"는입니다 LocalDateTime. 자정은 파리에서 몬트리올과는 다른 순간에, 그리고 시애틀오클랜드 에서는 또 다른 순간 에 일어난다 .

LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
LocalTime lt = LocalTime.MIN ;   // 00:00:00
LocalTime ldt = LocalDateTime.of( ld , lt ) ;  // Xmas morning anywhere. 

또 다른 예로 "Acme Company는 전 세계 각 공장에서 점심 시간이 오후 12시 30 분에 시작한다는 정책을 가지고 있습니다"입니다 LocalTime. 진정한 의미를 가지려면 슈투트가르트 공장에서 12:30, 라바트 공장에서 12:30, 시드니 공장 에서 12:30의 순간을 파악하기 위해 타임 라인에 적용해야합니다 .

예약 약속

사용할 또 다른 상황 LocalDateTime은 향후 이벤트를 예약하는 것입니다 (예 : 치과 의사 약속). 이러한 약속은 미래에 정치인들이 시간대를 재정의 할 위험에 처하기에 충분할 수 있습니다. 정치인들은 종종 예고를 거의하지 않거나 전혀 경고하지 않습니다. 정치인이 시계를 어떻게 연주하는지에 관계없이 "다음 1 월 23 일 오후 3시"를 의미하는 경우 순간을 녹화 할 수 없습니다. 해당 지역에서 일광 절약 시간제를 채택하거나 떨어 뜨린 경우 오후 3 시가 오후 2시 또는 오후 4 시로 바뀌는 것을 볼 수 있습니다. 예를 들어.

약속의 경우 a LocalDateTime와 a ZoneId를 별도로 보관하십시오. 나중에 일정 LocalDateTime::atZone( ZoneId )을 생성 할 때 ZonedDateTime개체 생성 을 호출 하여 순간을 결정 합니다.

ZonedDateTime zdt = ldt.atZone( z ) ;  // Given a date, a time-of-day, and a time zone, determine a moment, a point on the timeline.

필요한 경우 UTC로 조정할 수 있습니다. 에서을 추출 Instant하십시오 ZonedDateTime.

Instant instant = zdt.toInstant() ;  // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock time.

알 수없는 영역

LocalDateTime시간대 나 오프셋을 알 수없는 상황에서 사용할 수도 있습니다 .

나는이 경우가 부적절하고 현명하지 않다고 생각한다. 영역 또는 오프셋이 의도되었지만 결정되지 않은 경우 잘못된 데이터가있는 것입니다. 의도 된 통화를 모르고 제품의 가격을 저장하는 것과 같습니다. 좋은 생각이 아닙니다.

모든 날짜-시간 유형

완전성을 위해 다음은 Java의 최신 및 레거시뿐만 아니라 SQL 표준에 의해 정의 된 모든 가능한 날짜-시간 유형의 표입니다. 이것은 Instant& LocalDateTime클래스를 더 큰 컨텍스트에 배치하는 데 도움이 될 수 있습니다 .

Java (현대 및 레거시) 및 SQL 표준의 모든 날짜-시간 유형 표.

JDBC 4.2 설계에서 Java 팀이 선택한 이상한 점에 주목하십시오. 가장 일반적으로 사용되는 두 가지 클래스 &를 제외한 모든 java.time 시간 을 지원하기로 선택했습니다 .InstantZonedDateTime

그러나 걱정하지 마십시오. 우리는 쉽게 앞뒤로 변환 할 수 있습니다.

변환 중 Instant입니다.

// Storing
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject(  , odt ) ;

// Retrieving
OffsetDateTime odt = myResultSet.getObject(  , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;

변환 중 ZonedDateTime입니다.

// Storing
OffsetDateTime odt = zdt.toOffsetDateTime() ;
myPreparedStatement.setObject(  , odt ) ;

// Retrieving
OffsetDateTime odt = myResultSet.getObject(  , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZone( z ) ; 

java.time에 대하여

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 많은 예제와 설명을 보려면 스택 오버플로를 검색하십시오. 사양은 JSR 310 입니다.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이 필요없고 수업이 필요 없습니다 .java.sql.*

java.time 클래스는 어디서 구할 수 있습니까?

Java 또는 Android 버전과 함께 사용할 java.time 라이브러리 표

ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 입증 된 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .


39
좋은 대답입니다. 나는 약간의 혼란 (적어도 나의 것)은 Local명명 에서 비롯된 것이라고 생각합니다 . 내가 Local있는 곳과 내가있을 때 (?!)와 관련된 수단에 대한 나의 직관은 그것이 그것이 실제로 무엇이 될 것이라고 믿게한다 ZonedDateTime.
mkobit

4
예, 혼란 스럽습니다. 그렇기 때문에 java.time DateTime이 이전의 Joda-Time ( ZonedDateTime)에서 사용 하는 클래스 이름에 'Zoned'라는 단어를 영리하게 추가 하여 "로컬"클래스와의 차이점을 강조한 이유 입니다. "로컬"이라는 이름은 "특정 지역에 적용해야하는 필요성"의 약어로 생각하십시오.
Basil Bourque

2
단어의 접두어 Local는 java.util 패키지와 구별되는 방법 일 수도 있지만 어떻게 든 더 나은 단어 선택이있을 수 있다고 생각합니다.
vphilipnyc

2
@simonh 반대로… 그 신입 사원이 생명 보험을 포함한 자신의 혜택을 설명하는 채용 서류에 서명 한 다음 트럭에 닿아 죽이기 위해서만 커피를 마시기 위해 신입 사원을 고용 할 때 많은 사람들이있을 것입니다. 새로운 고용이 발효 된 정확한 순간을 알고 자하는 인사 매니저, 보험 에이전트 및 변호사.
Basil Bourque

2
@simonh 네, "현지"날짜 시간이 적절한 경우가 있습니다. 내 답변에 언급 된 것 외에도, 비즈니스에서 또 다른 일반적인 사례는 정치인이 표준 규칙을 변경할 수있을 정도로 충분히 두 달 이상 약속을 지키는 것입니다. 정치인은 일광 절약 시간제 (DST)를 켜거나 끌 때 날짜를 변경하거나 DST를 영구적으로 켜거나 끄는 등의 날짜를 자주 변경합니다.
Basil Bourque

20

한 가지 주요 차이점은의 Local일부입니다 LocalDateTime. 독일에 거주하고 LocalDateTime인스턴스를 생성 하고 다른 사람이 미국에 거주하며 같은 순간에 다른 인스턴스를 생성하는 경우 (시계가 올바르게 설정되어있는 경우) 해당 객체의 값은 실제로 달라집니다. Instant표준 시간대와 독립적으로 계산되는에 적용되지 않습니다 .

LocalDateTime시간대없이 날짜와 시간을 저장하지만 초기 값은 시간대에 따라 다릅니다. Instant의이 아닙니다.

또한 LocalDateTime일, 시간, 월과 같은 날짜 구성 요소를 조작하는 방법을 제공합니다. 은 Instant하지 않습니다.

Instant의 나노초 정밀도 이점과 LocalDateTime의 시간대 부분을 제외하고

두 클래스 모두 동일한 정밀도를 갖습니다. LocalDateTime시간대를 저장하지 않습니다. : 당신은 잘못된 가정에 큰 실수 할 수 있기 때문에, 철저하게 JavaDoc을 읽기 인스턴트LocalDateTime을 .


영역 + 정밀도 부분을 잘못 읽어서 죄송합니다. 위의 게시물에서 반복하여 죄송합니다. 단일 시간대 응용 프로그램을 고려할 때 어떤 유스 케이스에서 LocalDateTime을 선호합니까?
마누엘 알다 나

1
날짜 및 / 또는 시간이 필요할 때마다 LocalDateTime을 사용합니다. 몇 시간, 몇 분 정도. 예를 들어 Instant를 사용하여 실행 시간을 측정하거나 sth의 내부 필드를 저장합니다. 귀하의 경우와 같이 다음 런을 계산합니까? LocalDateTime은 적절 해 보이지만 의견입니다. 언급했듯이 둘 다 사용할 수 있습니다.
Dariusz

더 자세히 설명해 주 LocalDateTime stores date and time without timezone, but it's initial value is timezone dependent시겠습니까? 초기 값은 무엇이며 어떻게 시간대에 의존합니까? 감사.
최대

12

당신은 틀 렸습니다 LocalDateTime: 그것은 시간대 정보를 저장하지 않으며 나노 초 정밀도를 가지고 있습니다. Javadoc 인용 (강조 광산) :

ISO-8601 캘린더 시스템에서 시간대가없는 날짜-시간 ( 예 : 2007-12-03T10 : 15 : 30).

LocalDateTime은 날짜-시간을 나타내는 변경 불가능한 날짜-시간 객체이며, 종종 연월일-시-분-초로 표시됩니다. 년, 요일 및 주와 같은 다른 날짜 및 시간 필드에도 액세스 할 수 있습니다. 시간은 나노초 정밀도로 표시됩니다 . 예를 들어 "2007 년 10 월 2 일 13 : 45.30.123456789"값은 LocalDateTime에 저장할 수 있습니다.

이 둘의 차이 Instant는 Epoch (01-01-1970) 와의 오프셋을 나타내며, 따라서 타임 라인의 특정 순간을 나타냅니다. Instant지구의 두 곳에서 동시에 생성 된 두 물체는 정확히 같은 값을 갖습니다.


단일 시간대 응용 프로그램을 고려할 때 어떤 사용 사례에서 LocalDateTime을 선호합니까?
마누엘 알다 나

3
@manuelaldana 그것은 맛의 문제입니다. 사용자 관련 (생일 ...)에는 LocalDateTime을 선호하고 컴퓨터 관련 (실행 시간 ...)에는 Instant를 선호합니다.
Tunaki

2
@manuelaldana 존재하지 않는 경우 단일 시간대 앱은 거의 없습니다. 현지 바로크 음악 클럽을 위해 준비한 작은 앱의 시간대를 무시하고 벗어날 수 있습니다. 그러나 여행하는 사람들에게 (그리고 시간대를 넘어) 사람들에게 이벤트를 게시해야하는 즉시, 캘린더 앱이 필요에 따라 조정할 수 있도록 시간대에 연결된 데이터를 원할 것입니다. 모든 앱에서 표준 시간대로 작업하는 법을 배우는 것이 좋습니다.
Basil Bourque

@Tunaki 마지막 단락에서 'offset'이라는 단어를 사용하는 것이 혼란 스럽습니다. 이 단어는 날짜-시간 작업에서 특정 의미를 갖기 때문에 여기서 사용하는 것이 도움이되지 않을 수 있습니다.
Basil Bourque

0

Instant 자오선 (그리니치)의 시간에 해당합니다.

반면 LocalDateTimeOS 시간대 설정에 대해, 및

오프셋 또는 시간대와 같은 추가 정보가 없으면 순간을 나타낼 수 없습니다.


2
인스턴트는 GMT가 아닌 UTC를 기반으로합니다.
Torsten Ojaperv '
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.