Study/spring

[Java] Spring Boot 3 @DateTimeFormat 날짜 유효성 검사 사용법

 

@DateTimeFormat 어노테이션을 사용하면 입력 형식을 지정해서 입력값을 날짜나 시간 객체로 변환받을 수 있습니다.

예를 들어, 입력 형식을 "yyyy-MM-dd"로 지정하면 입력값이 형식에 맞는지 검증한 후 날짜 객체로 변환합니다.

 

사용 방법

@DateTimeFormat 어노테이션을 사용하기 위한 컨트롤러를 생성합니다.

import java.time.LocalDate;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.Getter;

@RestController
public class DateValidController {

    @GetMapping("/valid/date")
    public ValidObject validDate(@Valid ValidObject object) {
        return object;
    }

    @Getter
    @AllArgsConstructor
    public static class ValidObject {
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate date;
    }
}

 

@DateTimeFormat(pattern = "yyyy-MM-dd") 형식으로 사용했습니다.

만약 입력값이 형식에 맞다면 입력값을 LocalDate 객체로 변환합니다.

 

형식에 맞게 값을 입력하면 유효성 검사를 통과할 수 있습니다.

@DateTimeFormat 유효성 검사 통과
@DateTimeFormat 유효성 검사 통과

통과하지 못하면 다른 valid 어노테이션처럼 예외가 발생합니다.

 

@DateTimeFormat 유효성 검사 통과 실패
@DateTimeFormat 유효성 검사 통과 실패

 

yyyy-MM-dd로 설정했는데 yyyyMMdd 형태로 입력해서 유효성 검사를 실패했습니다.

입력값을 yyyyMMdd로 받고싶다면 @DateTimeFormat(pattern="yyyyMMdd") 형태로 사용하면 됩니다.

 

LocalDate, LocalDateTime, Date 등의 날짜 객체면 @DateTimeFormat을 사용한 유효성 검사가 가능합니다.

@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate localDate;

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;

@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date date;

LocalDate, LocalDateTime, Date 객체 유효성 검사 결과
LocalDate, LocalDateTime, Date 객체 유효성 검사 결과

 

 

 

 

주의사항

다른 객체를 사용하는 경우

@DateTimeFormat을 사용할 때 주의할 점은 입력값을 받는 객체가 날짜나 시간 관련 객체여야 합니다.

@DateTimeFormat(pattern = "yyyyMMdd")
private String stringDate;

입력값을 String 객체로 받게되면 유효성 검사를 진행하지 않습니다.

String 객체로 받으면 유효성 검사 진행하지 않음

 

@RequestBody

@DateTimeFormat은 @RequestBody에서는 동작하지 않습니다.

@PostMapping("/valid/date")
public ValidObject validDateForPost(@Valid @RequestBody ValidObject object) {
    return object;
}

@Getter
@AllArgsConstructor
public static class ValidObject {
    @DateTimeFormat(pattern = "yyyyMMdd")
    private LocalDate localDate;
}

@RequestBody에서는 동작하지 않음

만약에 @RequestBody에서 유효성 검사를 하고싶으면 @JsonFormat을 사용하면 된다고 합니다.

 

 

 

 

다른 사용 방법

@DateTimeFormat 어노테이션을 사용하는 다른 방법에 대해 소개드리겠습니다.

 

ISO

@DateTimeFormat 어노테이션에서 사용할 수 있는 값 중에 ISO가 있습니다.

 

다음과 같이 사용하면 됩니다.

@DateTimeFormat(iso = ISO.DATE)
private LocalDate localDate;

@DateTimeFormat(iso = ISO.DATE_TIME)
private LocalDateTime localDateTime;

@DateTimeFormat(iso = ISO.TIME)
private LocalTime localTime;

 

ISO를 사용하면 pattern으로 형식을 일일이 지정하지 않아도 된다는 장점이 있습니다.

만약에 yyyy-MM-dd처럼 많이 사용되는 포맷이라면 패턴 문자열을 직접 쓰지 않고 ISO.DATE 객체를 사용하면 됩니다.

 

사용 결과는 다음과 같습니다.

@DateTimeFormatter iso 사용 결과
@DateTimeFormatter iso 사용 결과

ISO.DATE = yyyy-MM-dd

ISO.DATE_TIME = yyyy-MM-ddTHH:mm:ss.SSSXXX

ISO.TIME = HH:mm:ss.SSSXXX

이렇게 적용이 되지만, 시간 형식의 경우 밀리초 단위는 빠져도 괜찮습니다.

 

fallbackPatterns

fallbackPattern은 pattern이나 iso에서 설정한 형식에 맞지 않을 때 대체할 형식을 지정해주는 옵션입니다.

@DateTimeFormat(iso = ISO.DATE, fallbackPatterns = {"yyyyMMdd", "yyyy_MM_dd"})
private LocalDate localDate;

ISO.DATE 형식(yyyy-MM-dd)에 맞지 않을 때 fallbackPatterns에 있는 패턴과 매칭을 시도합니다.

 

fallbackPatterns에도 맞는 형식이 없다면 유효성 검사에 실패합니다.

fallbackPatterns에도 맞는 패턴이 없을 때 유효성 검사 실패
fallbackPatterns에도 맞는 패턴이 없을 때 유효성 검사 실패