[Java] LocalDateTime, ZonedDateTime, Instant
Java의 Date에 대한 역사는 네이버 기술블로그에서 자세하게 설명해놨다.
(https://d2.naver.com/helloworld/645609)
Date의 문제점
- 불변 객체가 아니다(not immutable)
- int 상수 필드의 남용
- 헷갈리는 월 지정
- Date는 0부터 시작한다. 실제 Calendar.OCTOBER의 값은 9이다.
- 일관성 없는 요일 상수
Calendar.get(Calendar.DAY_OF_WEEK)
에서 반환한 요일은 int 값으로, 일요일이 1이다. 따라서, 수요일은 4가 되지만Date.getDay()
의 값은 일요일이 0, 수요일이 3이다.- 현재
Date.getDay()
는@Deprecated
되었다.
- Date와 Calendar의 역할 분담
- 오류에 둔감한 시간대 ID지정
java.util.Date
하위 클래스 문제
Joda-Time
- 지역 시간과 시간대가 지정된 시간을 구분
- 불변 객체
- 월의 int 값과 명칭 일치 - 1월은 int 1
- 13월 같이 잘못 된 월이 넘어가면 객체 생성 시점에서
IllegalFieldValueException
을 던진다. - 요일 상수는 일관되게 사용
- 잘못 된 시간대 ID 설정시
IllegalArgumentException
을 던진다. - Spring 프레임워크에서도 기본 지원
- Hibernate 프레임워크에서도 기본 지원
LocalDateTime
Local이 접두어로 붙은 것에서 유추할 수 있듯이 여러 지역의 시간대(Time Zone) 정보는 포함하지 않는다. KST나 UTC처럼 시간대를 지정하는 것이 정확한 표현이지만, 실제 활용에서는 이러한 시간대는 잘 사용되지 않고 방해가될 수 있으므로 시간대가 필요없는 작업에서 사용을 고려한다.
ex) 생일, 기념일 등
ZonedDateTime
LocalDateTime에서 시간대(Time Zone)치 추가된 클래스로 다른나라와 이벤트 시간을 맞추기 위해 사용하는 클래스
다음과 같은 특징을 가진다.
- 요일 클래스는 Enum 상수로 제공한다.
- static factory 메서드를 많이 사용한다.
of()
,Instant.from()
,DateTimeFormatter.ofPattern()
- Joda-Time보다 클래스별 역할이 더 세분화 되어있다. ex) ZoneRules
- 서머타임 기간이면
TimeZoneRules.isDaylightSavings()
의 값이 true이다. - 잘못 지정된 시간대 ID에는
ZoneRulesException
을 던진다.
ZoneOffset vs ZonedId
ZoneId
는 타임존, ZonedOffset
은 시차를 나타낸다.
ZoneOffset
은 UTC기준으로 고정된 시간 차이를 양수나 음수로 나타내는 반면에 ZonedId
는 이 시간 차이를 타임존 코드로 나타낸다.
System.out.println(ZonedDateTime.now(ZoneOffset.of("+09:00")));
System.out.println(ZonedDateTime.now(ZoneId.of("Asia/Seoul")));
2021-05-31T23:22:43.086+09:00
2021-05-31T23:22:43.096+09:00[Asia/Seoul]
UTC 기준으로 시간을 나타낸 것으로, KST(한국 시간)은 UTC보다 9시간이 빠르기 때문에 UTC +09:00으로 표기한다.
Instant
UNIX의 timestamp는 Year 2038 Problem을 가지고 있기 때문에 다른 타입으로 바꿀 것을 추천한다.
그렇기에 나온게 Instant
클래스다.
Instant는 UTC의 타임 라인에 있는 순간으로, 1970년 1월 1일 UTC의 첫 번째 순간 이후 현재 시간까지의 나노초를 나타낸 값으로, 사용하기 편리한 클래스다.