java
의 다양한 날짜 데이터타입을 관리하기
LocalDateTime
OffsetDateTime
ZonedDateTime
Gitlab 파이프라인 관리하는 사이드 프로젝트중
{
"created_at": "2016-08-12T10:06:04.561Z",
"updated_at": "2016-08-12T10:09:56.223Z"
}
위와같은 json 응답값을 LocalDateTime
으로 파싱해서 받고싶은데 계속 에러가 발생...
자바에서 날짜 데이터타입들이 존재하는데,
사진에서 확인할수 있듯, 비슷한듯 약간씩 다른부분이 있다
무지성으로 사용하던 LocaDateTime
A date-time without a time-zone in the ISO-8601 calendar system,
such as {@code 2007-12-03T10:15:30}.
단순히 날짜와 시간을 담고있는 데이터타입
A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system,
such as {@code 2007-12-03T10:15:30+01:00}.
LocalDateTime
과 비교하여 offset
이라는 데이터를 하나 더 갖고있다
우리나라의 UTC+09:00
값을 가지고 있는것을 확인할 수 있다
A date-time with a time-zone in the ISO-8601 calendar system,
such as {@code 2007-12-03T10:15:30+01:00 Europe/Paris}.
OffsetDateTime
과 비교하여 zone
데이터를 하나 더 갖고있다
그리고 한국으로 되어있는것을 확인할 수 있다
UTC
가 추가된 날짜 데이터를 삽입했을 때, LocalDateTime
으로 파싱부터 안된다 >> InvalidFormatException
발생
그렇다면 ObjectMapper
에 LocalDateTime
데이터타입에 맵핑되어 들어오는 데이터에 대하여 커스텀한 Deserializer
를 추가하도록 한다
그리고 TimeZone
이 추가된 데이터가 들어온다면 내가 변환하고싶은 TimeZone
을 적용하여 역직렬화를, timeZone
이 없는 데이터가 들어온다면 단순히 LocalDateTime
데이터타입으로 역직렬화를 추가한다
@Configuration
class ObjectMapperConfig {
@Bean
fun objectMapper(): ObjectMapper{
val simpleModule = SimpleModule()
simpleModule.addDeserializer(LocalDateTime::class.java, TimeZoneDeserializer())
return ObjectMapper().registerModules(simpleModule)
}
inner class TimeZoneDeserializer(): JsonDeserializer<LocalDateTime>() {
override fun deserialize(jsonParser: JsonParser, deserializationContext: DeserializationContext): LocalDateTime {
return try {
InstantDeserializer.ZONED_DATE_TIME.deserialize(jsonParser, deserializationContext)
.withZoneSameInstant(ZoneId.of("+09:00"))
.toLocalDateTime()
}
catch (e: InvalidFormatException){
LocalDateTimeDeserializer.INSTANCE.deserialize(jsonParser, deserializationContext)
}
}
}
}
추가로, ZoneId
생성 메서드는 대부분의 값들을 파싱해주려고 노력하고 있다
그래서 현재는 .withZoneSameInstant(ZoneId.of("+09:00"))
으로 사용했지만 다음과 같이도 사용할 수 있다
.withZoneSameInstant(ZoneId.of("Asia/Seoul"))
.withZoneSameInstant(ZoneId.of("+09:00"))
TimeZone
이 적용되지 않은 값으로 들어왔을때는 그대로 반환하는 테스트 및 TimeZone
이 적용된 데이터가 들어왔을때 내가 Bean
으로 적용한 UTC+09:00
으로 변환되어 잘 들어오는 테스트코드는 다음과 같다
출처 : 조무래기 코딩 : Jackson Deserializer 커스텀을 통해 LocalDateTime에 타임존 반영하기!
코드 : https://github.com/superpangE/oneday_stduy/tree/date-deserializer