한국기준 날짜 데이터 입력받기

김민창·2024년 3월 24일
0
post-thumbnail

java의 다양한 날짜 데이터타입을 관리하기

  • LocalDateTime
  • OffsetDateTime
  • ZonedDateTime

Gitlab 파이프라인 관리하는 사이드 프로젝트중

{
  "created_at": "2016-08-12T10:06:04.561Z",
  "updated_at": "2016-08-12T10:09:56.223Z"
}

위와같은 json 응답값을 LocalDateTime으로 파싱해서 받고싶은데 계속 에러가 발생...


날짜 데이터타입

자바에서 날짜 데이터타입들이 존재하는데,

사진에서 확인할수 있듯, 비슷한듯 약간씩 다른부분이 있다


LocalDateTime

무지성으로 사용하던 LocaDateTime

A date-time without a time-zone in the ISO-8601 calendar system,
such as {@code 2007-12-03T10:15:30}.

단순히 날짜와 시간을 담고있는 데이터타입


OffsetDateTime

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 값을 가지고 있는것을 확인할 수 있다


ZonedDateTime

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 발생

그렇다면 ObjectMapperLocalDateTime 데이터타입에 맵핑되어 들어오는 데이터에 대하여 커스텀한 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

profile
개발자 팡이

0개의 댓글