이전에 Date, Calendar 대신 LocalDate, LocalDateTime을 사용하라는 글을 쓴 적이 있습니다.
[Java] Date, Calendar와 LocalDate, LocalDateTime 차이
그런데 개발한 서비스의 사용자가 한국이 아닌 다른 나라에 산다면.. LocalDateTime만으로는 살짝 부족할 것입니다.
예를 들어..
한국에 사는 강 씨가 글을 등록하고 30분 뒤, 영국에 사는 Law 씨가 글을 등록했습니다.
홈 화면에서 작성일 기준 내림차순으로 글이 정렬된다면 Law 씨의 글이 먼저 떠야 합니다.
하지만 LocalDateTime으로만 개발했다면...
작성자: 강
내용: 동원
작성일: 2023-12-28 10:00
작성자: Law
내용: Jude
작성일: 2023-12-28 1:30
강 씨의 글이 먼저 뜨게 됩니다.
LocalDateTime에는 UTC를 기준으로 한 시간대가 포함되지 않기 때문입니다.
UTC (Coordinated Universal Time)
협정 세계시. 국제 표준 시간의 기준으로 쓰이는 시각입니다.
영국이 그 기준이고, 이와 비교해 빠르고 느림을 +/-로 표현합니다.
영국 UTC+0:00
한국 UTC+9:00
이 UTC와의 시간차를 포함해 날짜를 표기하는 국제 표준이 ISO 8601 입니다.
참고 - https://jjhwqqq.tistory.com/292
ISO (International Organization for Standardization)
국제 표준화 기구. 여러 가지 국제 표준을 규정해 번호를 매겨왔습니다.
예로, 7비트의 문자 코드의 표준을 규정한 ISO 646이 있습니다.
개인적으로 저에게는 어린 왕자가 사는 B612보다도 익숙하지 않은 번호인데요ㅎ..
사실 ISO 646이 바로.. ASCII 아스키 코드입니다..!
여튼.. ISO에서 날짜 표기의 표준도 규정했습니다.
ISO 8601
ISO에서 국제 표준으로 정의한 날짜 및 시간 표기 형식입니다.
2023-12-28T10:00:00.000+09:00
'T' 앞에 날짜, 뒤에 시간, 그리고 마지막에 UTC와의 시간차를 표기합니다. 만약 UTC라면 'Z'를 표기합니다.
영국 2023-12-28T01:00:00.000Z
한국 2023-12-28T10:00:00.000+09:00
이 ISO 8601 형식으로 저장할 수 있게 해주는 게 OffsetDateTime 입니다.
참고
https://jodmsoluth.tistory.com/5
https://authentication.tistory.com/43
OffsetDateTime
LocalDateTime에서 ZoneOffset (UTC와의 시간차) 정보가 추가된 타입입니다.
여기에 ZoneRegion (시간대가 속한 지역) 정보도 추가된 타입은 ZonedDateTime 입니다.
LocalDateTime을 atOffset(), atZone() 메서드를 이용해 시간차와 지역 정보를 추가해 OffsetDateTime, ZonedDateTime으로 변환할 수 있습니다.
반대로 OffsetDateTime, ZonedDateTIme을 toLocalDateTime() 메서드를 이용해 LocalDateTime으로 변환할 수도 있습니다.
한국에서 2023년 12월 28일 10시에 현재 시간을 가져온다면 각각의 데이터 타입은 이렇게 저장됩니다.
LocalDateTime | 2023-12-28T10:00:00.000000 |
OffsetDateTime | 2023-12-28T10:00:00.000000+09:00 |
ZonedDateTime | 2023-12-28T10:00:00.000000+09:00[Asia/Seoul] |
Timestamp도 UTC를 기준으로 한 타입입니다.
다만 위와 같이 표현하지 않고, '1970년 1월 1일 00:00:00 UTC' 로부터의 경과 시간을 초로 환산하여 정수로 나타내기 때문에... ISO 8601보다 가독성이 떨어집니다.
또 Application에서 TimeZone을 UTC로 설정해 LocalDateTime을 이용하면서도 UTC 기준으로 저장되도록 할 수도 있습니다.
참고 - https://isntyet.github.io/java/Spring-boot-Timezone-설정하기/
결론
개발하는 서비스의 특성에 따라, 이미 개발된 기존 방식을 고려해서, DB 컬럼의 데이터 타입에 맞춰 알맞은 데이터 타입을 선택하시면 좋을 듯합니다ㅎㅎ
저는 DB로 PostgreSQL을 사용했는데, 날짜를 저장할 때 컬럼의 데이터 타입을 PostgreSQL에서 권장하는 timestamptz (timestamp with time zone) 로 지정했고, 이와 매핑되는 OffsetDateTime을 이용했습니다.
참고 - https://tada.github.io/pljava/use/datetime.html
+
timestamptz
PostgreSQL은 timestamp라는 데이터 타입으로 날짜와 시간을 저장합니다.
timestamp는 LocalDateTime과 마찬가지로 시간대에 대한 정보를 저장하지 않습니다.
timestamptz (timestamp with time zone) 는 날짜와 시간, 시간대(정확히는 시간차)에 대한 정보를 저장합니다.
'Web' 카테고리의 다른 글
Swagger API 문서를 웹에 올려 링크 불러오기 (2) | 2023.12.29 |
---|---|
[Spring] Swagger 적용하기 (2) | 2023.12.27 |
[Spring/Kotlin] Entity와 data class (2) | 2023.12.26 |
[Spring] Parameter 0 of constructor in A required a bean of type B that could not be found (3) | 2023.12.21 |
REST의 근원을 찾아서... (2) | 2023.12.20 |