카테고리 없음

[ZonedDateTime] 그리고 OffsetDateTime

sheriff 2022. 5. 31. 13:25

OffsetDateTime, ZonedDateTime

LocalDateTime 외에 OffsetDateTime, ZonedDateTime이 존재한다.

 

각각 어떤 값을 가지는지 디버깅 모드에서 확인해보자.

우선 각각을 .now() 메소드를 통해 현재 시간을 가져온다.

LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();

이제 디버깅 모드에서 각각의 값을 확인해보자.

intellij 의 debugger 창 캡쳐

  • LocalDateTime : 날짜, 시간
    • 날짜와 시간만 존재한다.
    • 시차 정보가 없기 때문에 다른 위치에 있는 서버에서 동시에 저장되는 경우 다른 시간으로 저장 되며 같은 시간이라는 것을 알 수 없음
  • OffsetDateTime : 날짜, 시간, offset(GMT 기준)
    • LocalDateTime에 offset 정보가 추가 됨
    • 시차 정보가 있기 때문에 다른 위치에 있는 서버에서 동시에 저장되는 경우 시차 정보를 통해 같은 시간임을 알 수 있음
  • zonedDateTime : 날짜, 시간, offset(GMT 기준), zone
    • OffsetDateTime에 zone 정보가 추가 됨
    • 시차 정보와 함께 지역 정보까지 확인 가능

LocalDateTime + ZoneId

atZone을 사용하면 LocalDateTime 에 zone 을 추가할 수 있다.

LocalDateTime now = LocalDateTime.now();
ZonedDateTime saoPauloZonedDateTime = now.atZone(ZoneId.of("America/Sao_Paulo"));
ZonedDateTime seoulZonedDateTime = now.atZone(ZoneId.of("Asia/Seoul"));

  • LocalDateTime에 Zone  정보를 추가하여 Zone(Region), offset 정보를 나타냄

ZonedDateTime에서 Zone, Offset 을 제거한 LocalDateTime 으로 변환도 쉽습니다.

LocalDateTime localDateTime = seoulZonedDateTime.toLocalDateTime();

withZoneSameInstance를 사용하면 ZonedDateTime에 다른 Zone으로 변경도 가능합니다.

ZonedDateTime now = LocalDateTime.now().atZone(ZoneId.of("Asia/Seoul"));
ZonedDateTime londonZonedDateTime = now.withZoneSameInstant(ZoneId.of("Europe/London"));

output : 
now = 2022-05-31T14:17:24.852151+09:00[Asia/Seoul]
londonZonedDateTime = 2022-05-31T06:17:24.852151+01:00[Europe/London]

Period, Duration

Perioed.between 메소드는 LocalDate 만을 매개변수로 받는다.

따라서 OffsetDateTime이나 ZonedDateTime 을 사용할 경우 .toLocalDate() 메소드를 사용하면 된다.

하지만 Duration.between 메소드의 경우 Temporal(Interface) 을 매개변수로 받는데, LocalDateTime, OffsetDateTime, ZonedDateTime 모두 Temporal을 구현한 클래스이므로 사용이 가능하다.

물론 LocalDateTime과 ZoneDateTime을 각각 다르게 넘기는 것도 가능하다.

LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("America/Sao_Paulo"));

Duration duration = Duration.between(localDateTime, zonedDateTime);