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의 첫 번째 순간 이후 현재 시간까지의 나노초를 나타낸 값으로, 사용하기 편리한 클래스다.

참고 자료