서론
글로벌 서비스를 만들려고 하면 시간에 대한 고민이 빠질 수 없다.
기본적으로 클라이언트에서 어떻게 요청을 받아야 할지 고민했는데 크게 두가지 방법이 생각이 났다.
1. Unix Timestamp
2. ISO8601
Unix Timestamp은 '1970년 1월 1일 00:00:00 협정 세계시(UTC)' 부터의 경과 시간을 초로 환산하여 정수로 나타낸 것이라고 하는데 단번에 어떤 날짜인지 알 수 없듯이 가독성이 떨어진다는 단점이 있고 Timezone을 포함하여 UTC를 클라이언트가 보내줄 거라는 보장도 없어서 ISO8601을 사용하기로 했다
아무래도 JAVA 8 이후에 Java.Time 패키지가 생기면서 기본적으로 ISO8601이 표준이라 사용하는 이유가 크다.
ISO8601의 날짜 + 시간을 표현하는 기본적인 형식은 다음과 같다
YYYY-MM-DDThh:mm:ss.sssZ
문자 T를 기준으로, 왼편에는 날짜, 오른편에는 시간을 표기하며, Z는 zone offset을 의미한다.
zone offset은 UTC 의 시차를 의미하는데
우리 나라를 기준으 UTC+09:00(KST, 한국 표준시)를 사용한다.
본론
ISO 8601을 사용하기로 결정한 다음에는 시간 타입을 결정해야 하는데 Java.Time 패키지에는 기본적으로 LocalDateTime, OffsetDateTime, ZonedDateTime 3가지를 지원한다.
LocalDateTime
Offset 정보 등과 같은 부가 정보가 없이, 날짜와 시간 정보만 표기하는 클래스이다.
Offset정보가 없이 클라이언트가 보내는 시간이 어느 지역 기준 시간인지 알 수가 없는 제약이 있다.
따라서 글로벌 서비스를 생각하고 있으면 OffsetDateTime이나 ZonedDateTime을 사용해야한다.
OffsetDateTime
LocalDateTime에서 Zone offset을 알 수 있어 글로벌 서비스 구현에 적합하다.
ZonedDateTime
Zone Id는 ISO8601에는 포함되지는 않는다 하지만, summer time같은 특수한 처리를 하기 위해 사용한다.
결론
결론적으로 나는 OggsetDateTime을 사용하기로 했는데
OffsetDateTime을 사용하는 이유는 데이터베이스에 UTC 기준으로 시간을 표현하기 위함이다. (timestamp with zone)
그래서 나도 대부분 아래 처럼 OffsetDateTime을 사용하고 있다.
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
@JsonSerialize(using = OffsetDateTimeSerializer.class)
@JsonDeserialize(using = OffsetDateTimeDeserializer.class)
private OffsetDateTime scheduledAt;
GMT 스타일의 ISO8601 문자열을 Date로 변환하려고 pattern을 보면 SSSXXX를 볼 수 있는데
XXX는 +09:00를, X는 +09를 나타낸다.
댓글