Java 8, 타임존이 포함된 ISO 8601 문자열을 LocalDateTime으로 변환하기

타임존?

  • 과거에는 개발자들이 타임존을 크게 신경 쓰지 않았다. 하지만 시스템 또는 플랫폼 간의 의사소통 방식으로서의 API가 대중화되고 서비스 지역이 전세계로 확장되면서 API 요청 및 응답에 있어 타임존 정보를 적절하게 인식하고 가공하는 작업이 중요해졌다. 이번 글에서는 Java 8에서 타임존이 포함된 날짜/시간 정보를 다루는 방법을 소개하고자 한다.

타임존 포함 ISO 8601 문자열의 표현

  • 날짜/시간 및 타임존을 다루는 국제적인 규약은 상당히 다양하다. RFC 822, 1036, 1123, 2822, 3339, ISO 8601 등이 있다. 여기서는 ISO 8601RFC 3339와 관련된 표기법을 소개한다.
// 로컬 시간을 의미하는 ISO 8601 문자열
2017-11-06T15:00:00.000

// UTC(GMT) 시간을 의미하는 ISO 8601 문자열
2017-11-06T06:00:00.000Z

// 로컬 시간을 의미하면서 UTC(GMT) 대비 +09:00 임을 의미하는 ISO 8601 문자열
2017-11-06T15:00:00.000+09:00
  • 2017-11-06T15:00:00.000ISO 8601의 기본 형식이다. 해당 시간이 로컬 시간 임을 의미한다.

  • 2017-11-06T06:00:00.000Z와 같이 뒤에 Z 식별자를 추가하면 해당 시간이 UTC(GMT) 시간 임을 의미한다.

  • 2017-11-06T15:00:00.000+09:00와 같이 뒤에 Z 대신 +HH:mm 식별자를 추가하면 해당 시간이 로컬 시간이면서 UTC(GMT)09:00 만큼 차이가 남을 의미한다. 이 형식의 장점은 인간이 손쉽게 추가적인 계산 없이 로컬 시간을 인지하면서 추가적으로 타임존 정보까지 제공하기 때문에 가장 인간친화적이라고 할 수 있다.

일광 절약 시간제의 고려

  • 일광 절약 시간제(Daylight Saving Time; DST)는 우리에게는 서머 타임으로 유명한 개념으로 하절기에 표준시를 원래보다 1시간 앞당겨 쓰는 것을 의미한다. 일광 절약 시간제의 적용 여부와 시기는 국가마다 다르며, 미래에는 각 국가의 법이 어떻게 변할지 아무도 알 수 없다. 일광 절약 시간제가 적용된 국가(대표적으로 미국)의 시간 정보에 있어 유의할 점은 미래 시간의 경우 정확한 UTC 시간을 예측할 수 없다는 것이다. 따라서 이 경우 내부적으로 로컬 시간으로 저장해야 한다.

타임존 포함 ISO 8601 문자열의 LocalDateTime 변환

try {
    // 타임존이 포함된 ISO 8601 문자열로부터 Asia/Seoul 타임존의 LocaDateTime 오브젝트 획득
    LocalDateTime dateTime = LocalDateTime.from(

        Instant.from(
            DateTimeFormatter.ISO_DATE_TIME.parse("2017-11-06T06:02:00.000Z")
        ).atZone(ZoneId.of("Asia/Seoul"))
    );

// 파씽 오류시 DateTimeParseException 예외 발생
} catch (DateTimeParseException ex) {

    // 예외 처리 로직 작성
}
  • DateTimeFormatter.ISO_DATE_TIME.parse()는 파라메터로 앞서 언급한 3가지 표기법을 모두 지원한다. 지원하지 않는 표기법의 경우 DateTimeParseException 예외를 발생시킨다.

  • LocalDateTime은 순수하게 로컬 시간 만을 표현하는 클래스이다. 앞서 인식된 문자열을 로컬 시간으로 변환하기 위해서는 현재 시스템에서 기준이 되는 타임존 정보를 알려주어야 한다. 본 예제에서는 Asia/Seoul를 예로 들었다. Instant.atZone(ZoneId.of("Asia/Seoul"))은 앞서 인식된 시간 정보를 Asia/Seoul 타임존으로 변환한다. Instant.atOffset(ZoneOffset.of("+09:00"))으로 변환해도 결과는 동일하다. 지원하지 않는 타임존 또는 타임존 오프셋의 경우 DateTimeException 예외를 발생시킨다.

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고