자바 8에는 많은 변화들이 있었고 그 중 하나가 java.time 모듈인데요. 이러한 java time에 대해서 Jackson이라는 자바의 json 변환 라이브러리에서는 JavaTimeModule을 통해 지원하고 있습니다.
이번에는 자바 타임 모듈의 여러 클래스와 jackson의 javaTimeModule이 어떻게 지원(변환)하는 지 함께 알아보겠습니다.
Duration
은 내부적으로 seconds와 nanos를 가지고 있고 이를 .으로 구분하여 숫자형으로 변환합니다.
public final class Duration {
private final long seconds;
private final int nanos;
}
{
"duration": 86400.000000000 // Duration.ofDays(1)
}
Period
는 년, 월, 일 데이터를 가지고 있는 클래스이며 ISO 8601의 기간 표현 방식을 문자열로 변환됩니다.
public final class Period {
private final int years;
private final int months;
private final int days;
}
{
"period": "P1Y1M1D" // Period.of(1,1,1)
}
Instant
는 Duration
과 같이 seconds와 nanos로 구성되어 있고 duration과 동일하게 숫자형태로 변환됩니다. 여기서 중요한 것은 소숫점 9번째 자리까지 표현될 수 있다는 점입니다.
public final class Instant {
private final long seconds;
private final int nanos;
}
{
"instant": 1702218238.385442000 // Instant.now()
}
LocalDate
클래스의 경우에는 Period
와 동일하게 years, months, days로 구성되어 있으며 이를 숫자 배열형태로 변환합니다.
public final class LocalDate {
private final int years;
private final int months;
private final int days;
}
{
"localDate": [2023,12,10]
}
LocalTime
클래스는 hour, minute, second, nano 필드로 구성되어 있으며 이를 숫자 배열형태로 변환합니다.
public final class LocalTime {
private final byte hour;
private final byte minute;
private final byte second;
private final int nano;
}
{
"localTime": [23,23,58,385463000]
}
LocalDateTime
클래스는 LocalDate
와 LocalTime
타입의 필드를 각각 가지고 있으며 이를 모두 포함하는 하나의 숫자 배열로 변환됩니다.
public final class LocalDateTime {
private final LocalDate date;
private final LocalTime time;
}
{
"localDateTime": [2023,12,10,23,23,58,385469000]
}
OffsetTime
클래스는 ZoneOffset
과 LocalTime
타입의 필드를 각각 가지고 있으며 ZoneOffset
정보는 문자열로, LocalTime
정보는 숫자로 된 배열로 변환됩니다.
public final class OffsetTime {
private final LocalTime time;
private final ZoneOffset offset;
}
{
"offsetTime": [23,23,58,385477000,"+09:00"]
}
OffsetDateTime
클래스는 ZoneOffset
과 LocalDateTime
타입의 필드를 각각 가지고 있으나 Instant
와 동일한 초(second)와 나노초의 형태의 숫자로 변환됩니다.
public final class OffsetTime {
private final LocalTime time;
private final ZoneOffset offset;
}
{
"offsetDateTime": 1702219187.624879000
}
ZoneId
클래스는 추상 실드 클래스로 ZoneOffset
과 ZoneRegion
이 상속하고 있습니다. ZoneRegion
의 경우 string id를 통해 time zone id를 가지고 있으며 이를 문자열로 변환하고 있습니다.
public abstract sealed class ZoneId permits ZoneOffset, ZoneRegion {
}
final class ZoneRegion extends ZoneId {
private final String id;
}
{
"zoneId": "Asia/Seoul"
}
ZoneOffset
클래스는 ZoneId
를 상속하고 내부적으로 totcalSeconds를 가지고 있으며 이를 문자열로 변환하고 있습니다.
public final class ZoneOffset extends ZoneId {
private final int totalSeconds;
private final transient String id;
}
{
"zoneOffset": "+09:00"
}
ZoneDateTime
클래스는 LocalDateTime
, ZoneOffset
, ZoneId
를 필드로 가지고 있고 변환시에는 초와 나노초로 구성된 숫자로 변환됩니다.
public final class ZonedDateTime {
private final LocalDateTime dateTime;
private final ZoneOffset offset;
private final ZoneId zone;
}
{
"zonedDateTime": 1702219658.570394000
}
Year
클래스는 year 정보를 int로 가지고 있고 숫자로 변환됩니다.
public final class Year{
private final int year;
}
{
"year": 2023
}
YearMonth
클래스는 year과 month 정보를 int 타입으로 가지고 변환 시에 각각을 포함하는 숫자 배열로 변환됩니다.
public final class YearMonth {
private final int year;
private final int month;
}
{
"yearMonth": [2023,12]
}
MonthDay
클래스는 month와 day 정보를 int 타입으로 가지고 변환 시에 문자열로 변환됩니다.
public final class MonthDay {
private final int month;
private final int day;
}
{
"monthDay": "--12-10"
}
전체적인 클래스와 전체적인 규칙성을 볼 수도 있었지만 몇몇 변환 형태는 기대와 다를 수 있을 것 같습니다. 필요에 따라서 적절한 커스텀 직렬화/역직렬화 방식을 구현해야할 것 같습니다.