이번 글에서는 DateTime 관련 데이터를 다루면서
학습한 내용들을 정리해보려고 합니다.
Intro
ISO 8601 & RFC 3339
본격적으로 코드를 다루기에 앞서,
날짜, 시간 데이터를 표기하는 국제 표준에 대해 먼저 간략하게 알아보겠습니다.
ISO 8601
ISO(International Organization for Standardization)은 이름에서 알 수 있듯이
국제 표준을 다루는 기관입니다.
그리고 각 표준은 "ISO 넘버링" 으로 표기가되는데,
ISO 8601은 날짜와 시간 데이터 교환을 다루는 국제 표준을 뜻합니다.
날짜 + 시간을 표현하는 기본적인 형식은 다음과 같습니다.
- YYYY-MM-DDThh:mm:ss.sssZ
문자 T를 기준으로,
왼편에는 날짜, 오른편에는 시간을 표기하며,
Z는 zone offset을 의미합니다.
zone offset은 UTC 의 시차를 의미합니다.
예를 들어, 이 글을 쓰고 있는 현재 시간을
UTC+09:00(KST, 한국 표준시)를 사용하는 우리 나라를 기준으로 표기하면
2021-06-01T20:37:10+09:00 이됩니다.
해당 내용은 부수적인 내용인만큼,
최대한 간략하게 설명하여 많은 부분이 생략되어 있습니다.
더 자세한 내용이 궁금한 분들은 아래 링크를 참고해주세요.
https://ko.wikipedia.org/wiki/ISO_8601
RFC 3339
RFC(Request For Comments)는 인터넷 표준 등이 작성되어 있는 문서로,
해당 문서는 IETF(Internet Engineerging Task Force)에서 관리되고 있습니다.
RFC 3339 역시, ISO 8601과 마찬가지로
날짜, 시간의 표준에 대해 다루고 있습니다.
RFC 3339의 내용 대부분은 ISO 8601을 따르고 있지만,
차이점은 RFC 3339는 다음과 같이
문자 T 대신 공백으로 날짜와 시간을 구분할 수 있다는 점입니다.
2021-06-01 20:37:10+09:00
그럼 여기까지 시간을 표기하는 표준에 대해 간략하게 알아보고
본격적으로 날짜, 시간 데이터를 다루는 방법을 알아보겠습니다.
Java.Time
JDK 8(JSR 310) 이전에는 날짜와 시간을 Java에서 다루기에는 매우 불편했습니다.
때문에, Joda Time과 같은 라이브러리를 사용하여 날짜, 시간 데이터를 다뤘지만
JDK 8 이후부터는 Java.Time 패키지가 추가되면서 해당 데이터를 다루기가 매우 용이해졌습니다.
Java.Time 패키지는 기본적으로 ISO 8601 표준을 따르고 있으며
다음 그림에서는 Java.Time 패키지에 포함된 클래스들을 도식화해 보았습니다.
우리는 그 중 날짜와 시간 데이터를 모두 포함하는 클래스
LocalDateTime / OffsetDateTime / ZonedDateTime을 살펴보겠습니다.
LocalDateTime
Offset 정보 등과 같은 부가 정보가 없이,
날짜와 시간 정보만 표기하는 클래스입니다.
부가 정보가 없는만큼 다루기 편리할 수 있지만,
활용할 수 있는 한계가 있습니다.
저희 회사에서는 글로벌 결제 서비스를 운용하고 있습니다.
이때 미국 동부(UTC-05:00를 사용)에서 결제 시간 데이터를 보냈다고 가정해보겠습니다.
하지만 저희가 LocalDatetime만을 사용하여 offset 정보를 무시하고 있다면
실제 결제 시간과 저희가 관리하고 있는 결제 시간에 오차(5시간)가 발생하게 됩니다.
(물론, 결제를 요청한 나라를 알 수 있다면
결제 시간에 해당 나라의 offset 정보를 적용하여 문제를 해결할 수는 있습니다.)
OffsetDateTime
OffsetDateTime은 이름에서부터 알 수 있듯이
ZoneOffset 정보를 포함하는 날짜, 시간 데이터를 다룰 수 있는 클래스입니다.
ZonedDateTime
마지막으로 ZoneId 정보를 포함하는 ZonedDateTime 클래스입니다.
ZoneId는 ISO 8601에는 포함되지 않는 값으로,
해당 값은 summer time과 같이
특정 지역에 적용되어야하는 규칙을 위해 사용하는 값입니다.
Reference
- https://datatracker.ietf.org/doc/html/rfc3339#section-5
- https://ko.wikipedia.org/wiki/ISO_8601
- https://medium.com/easyread/understanding-about-rfc-3339-for-datetime-formatting-in-software-engineering-940aa5d5f68a
- https://perfectacle.github.io/2018/09/26/java8-date-time/
- https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html
- https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B4%91_%EC%A0%88%EC%95%BD_%EC%8B%9C%EA%B0%84%EC%A0%9C
- https://en.wikipedia.org/wiki/Coordinated_Universal_Time
'전체보기 > Spring' 카테고리의 다른 글
[JPA] JpaRepository vs CrudRepository(1) - Paging과 Sorting / QueryExampleExecutor (0) | 2022.01.01 |
---|---|
[Spring Boot] DateTime 다뤄보기(3) - Database에 저장하기 (0) | 2021.07.06 |
[Spring Boot] Custom Constraint / Validation 파헤치기 (0) | 2020.08.26 |
[Spring Boot]HikariCP 모니터링 - InstanceAlreadyExistsException 해결 (0) | 2020.07.19 |
[Spring Boot]HikariCP 모니터링 (0) | 2020.07.10 |