한국 시간으로 반환하기

문제 상황

문제원인

문제가 된 코드

@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
private final LocalDateTime createdAt;

해결책

구현 목표

  1. createdAt Type 을 LocalDateTime 에서 ZonedDateTime 으로 변경한다. 서비스 레이어에서 LocalDateTime 을 ZonedDateTime 으로 변경하고, timezone 정보와 시간 정보를 전달하게끔 한다.
@Getter
public class SingleChatResponseDto {
    private final Long chatId;
    private final SenderResponseDto sender;
    private final String content;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private final ZonedDateTime createdAt;

    @Builder
    public SingleChatResponseDto(Long chatId, SenderResponseDto sender, String content, LocalDateTime createdAt) {
        this.chatId = chatId;
        this.sender = sender;
        this.content = content;
        this.createdAt = createdAt.atZone(ZoneId.of("UTC")).withZoneSameInstant(ZoneId.of("Asia/Seoul"));
    }

  1. @Jackson2ObjectMapperBuilderCustomizer 사용하기 Front-end 로 들어오는 LocalDateTime (UTC) -> LocalDateTime (KST) 로 변경하기 장점 : 일괄적으로 들어오는 모든 datetime 을 KST 로 저장할 수 있다. @JsonFormat(timezone= “Asia/Seoul”) 처럼 매번 지정하지 않아도 된다. 단점 : 일괄적으로 들어오는 모든 datetime 을 KST 로 저장하기 때문에, configuration을 확인하지 않으면, 어떻게 시간이 변환되는지 확인할 수 없다. 마지막으로 DB 에 UTC 가 아닌 한국 시간으로 저장이 된다.
package com.tutorial.tailerbox.config;

import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

@Configuration
public class DateFormatConfiguration {

    private static final String dateFormat = "yyyy-MM-dd";
    private static final String datetimeFormat = "yyyy-MM-dd HH:mm:ss";

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return jacksonObjectMapperBuilder -> {
            jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone("Asia/Seoul"));
            jacksonObjectMapperBuilder.simpleDateFormat(datetimeFormat);
            jacksonObjectMapperBuilder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
            jacksonObjectMapperBuilder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(datetimeFormat)));
        };
    }