Java/개념

Java 8 ZonedDateTime vs OffsetDateTime 어떤 상황에서 쓰는게 적합한가?

TheWing 2022. 8. 19. 23:50

Java 8 ZonedDateTime vs OffsetDateTime 어떤 상황에서 쓰는게 적합한가?

들어가기 전에

  • 본 글은 회사 팀 내 세션 공유용 자료이며 이전 글 내용과 이어집니다.

OffsetDateTime

  • OffsetDateTime(LocalDateTime(날짜 + 시간) + ZoneOffset) 을 포함한다
  • Instant와 같이 나노초 정밀도로 타임라인에 순간을 저장한다
  • UTC/그리니치에서 오프셋을 추가하면 현지 날짜-시간을 얻을 수 있다.
  • 데이터베이스에 Timestamp를 저장하거나 네트워크를 통해 XML 문서에 Timestamp 를 통신하는 데 사용하는 것이 유리하다고 한다.

ZoneOffset

  • UTC 기준 시간을 표현한 것
  • 우리나라 Timezone(Asia/Seoul) 기준 UTC +09:00로 표기
  • ZoneOffsetZoneId를 상속 받았다.

ZonedDateTime

  • ZonedDateTime은 (OffsetDateTime + ZoneRegion)를 포함한다.
    • ZoneRegionTimezone을 나타낸 것이라고 보면된다. (ex. Asia/Seoul)
    • ZoneRegionZoneId를 상속 받았다.
  • 2022-08-19T22:36:41.559512100+09:00[Asia/Seoul] 와 같이 ISO-8601 달력 시스템 표준대를 따라서 표기한다.
  • Instant와 같이 나노초 정밀도로 타임라인에 순간을 저장한다.
  • 여기까지만 보면 OffsetDateTime과 차이가 무엇이냐는 궁금증이 있을 수 있다.
    Asia/Seoul을 쓰건 Asia/Tokyo 를 쓰건 어차피 UTC+09인데 뭔 상관이냐?
    OffsetDateTime 과 달리 ZonedDateTimeDST(Daylight Saving Time) 와 같은 써머 타임의 정보(ZoneRules로 판단)가 들어가 있다. 이 이유가 가장 크다
    1. DST를 사용하는 지역
    2. DST를 한번도 사용 안한 지역
    3. 과거에는 시행했지만 사용하지 않는 지역
      이렇게 지역이 3가지 분류로 나뉠 때 혼란스러워진다. 또한 CET(중앙유럽 표준시)CEST(중앙유럽 일광 절약 시간대) 를 사용 유무에 따라 계산하기 매우 까다롭다.
    • 이러한 부분을 ZoneRules로 DST를 완전히 인식하고 처리한다.
    • java는 CET와 CEST를 CET로 통일한다
      코드로 알아보자 1월 CET, 6월 CET 를 비교해보자
    •     ZonedDateTime winter = ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("CET"));
          System.out.println("winter = " + winter);
          ZonedDateTime summer = ZonedDateTime.of(2022, 6, 1, 0, 0, 0, 0, ZoneId.of("CET"));
          System.out.println("summer = " + summer);
      
          winter = 2022-01-01T00:00+01:00[CET]
          summer = 2022-06-01T00:00+02:00[CET]
  • 예상 했던 것과 다르게 같은 Offset이 찍히지 않는다.
  • OffsetDateTime은 이런 디테일한 부분을 처리할 수 없다.

결론

  • 데이터베이스나 네트워크를 통신하는데 사용하기에는 OffsetDateTime을 사용하는 것이 적절하고 글로벌 서비스에서는 ZonedDateTime을 사용하는 것이 더욱 바람직하다고 생각한다.

Reference