백엔드 개발 중 날짜 데이터를 다룰 때, 데이터베이스에 저장된 형식과 API 입출력 시의 형식이 불일치하는 문제가 자주 발생합니다. 예를 들어, DB에는 정상적으로 날짜가 저장되어 있지만 클라이언트로 응답할 때는 타임스탬프 형태로 출력되거나, 프론트엔드에서 전달한 문자열 형식의 날짜가 서버에서 제대로 파싱되지 않는 경우가 있습니다. 이러한 문제를 해결하기 위해 스프링에서는 @JsonFormat과 @DateTimeFormat 두 가지 어노테이션을 제공합니다.
@JsonFormat – 직렬화 시 날짜 형식 지정
@JsonFormat은 Java 객체를 JSON으로 변환할 때(즉, 서버 → 클라이언트 방향) 날짜 필드의 출력 형식을 지정하는 데 사용됩니다. 이 어노테이션은 Jackson 라이브러리에서 제공하므로 관련 의존성이 필요합니다.
Maven 기준으로 다음과 같은 의존성을 추가해야 합니다:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
실제 엔티티 클래스에 적용하는 예시는 다음과 같습니다:
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class UserDto {
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
private Date birthDate;
// Getter 및 Setter
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
여기서 pattern은 출력하고자 하는 날짜 형식을, timezone은 시간대를 명시합니다. GMT+8 대신 표준 IANA 시간대 ID인 Asia/Seoul 사용을 권장하며, 이는 더 명확하고 유지보수에 유리합니다.
이 어노테이션은 필드뿐만 아니라 getter 메서드에도 적용 가능하며, 동일한 효과를 얻을 수 있습니다.
@DateTimeFormat – 역직렬화 시 입력 형식 지정
@DateTimeFormat은 클라이언트로부터 전달된 문자열을 Java 날짜 객체로 변환할 때(즉, 클라이언트 → 서버 방향) 사용되는 형식을 정의합니다. 주로 컨트롤러에서 요청 데이터 바인딩 시 활용됩니다.
해당 기능을 사용하기 위해서는 Spring MVC와 함께 Joda-Time 또는 자바 8의 java.time 패키지가 필요하지만, 대부분의 최신 스프링 프로젝트에서는 기본적으로 지원됩니다. 별도로 Joda-Time을 사용한다면 다음 의존성을 추가할 수 있습니다:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.5</version>
</dependency>
컨트롤러 또는 DTO 클래스 내부에서 다음과 같이 사용합니다:
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
public class EventRequest {
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date eventStart;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private Date eventEnd;
// Getter 및 Setter 생략
}
위 코드에서 eventEnd 필드는 외부 입력 시 yyyy-MM-dd 형식을 허용하면서도, 응답 시에는 초 단위까지 포함된 더 자세한 형식으로 출력되도록 설정되었습니다. 이렇게 두 어노테이션을 동시에 사용하면 입출력 모두에서 형식을 세밀하게 제어할 수 있습니다.
사용 시 주의사항
- @JsonFormat: 직렬화(응답 생성)에만 영향을 미칩니다. 요청 바인딩에는 작동하지 않습니다.
- @DateTimeFormat: 요청 파라미터나 폼 데이터 바인딩 시에만 유효합니다. 응답에는 영향을 주지 않습니다.
- 시간대 설정을 누락하면 시스템 기본 시간대가 적용되어 예기치 않은 오프셋이 발생할 수 있으므로, 반드시 명시하는 것이 좋습니다.
최신 스프링 부트 환경에서는 java.time.LocalDate, LocalDateTime 등의 자료형과 함께 이 어노테이션을 사용하는 것이 일반적이며, Jackson 설정을 통해 전역적으로 기본 형식을 지정할 수도 있습니다.