개발/Spring
[Spring] 날짜 파라미터 처리하기
함수형 인간
2025. 3. 14. 06:56
1. String으로 받아서 직접 파싱 (가장 기본적인 방법):
- 클라이언트로부터 날짜를 String 형태로 받는다 (예: "2023-10-27").
- java.time.LocalDate, java.time.LocalDateTime, java.util.Date, java.text.SimpleDateFormat 등을 사용하여 직접 파싱.
Java
@GetMapping("/date")
public String processDate(@RequestParam("date") String dateString, Model model) {
try {
// java.time.LocalDate 사용 (Java 8 이상)
LocalDate date = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
model.addAttribute("parsedDate", date);
// java.util.Date 사용 (구 버전)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date2 = sdf.parse(dateString);
model.addAttribute("parsedDate2", date2);
} catch (DateTimeParseException | ParseException e) {
// 파싱 에러 처리
model.addAttribute("error", "Invalid date format. Please use yyyy-MM-dd.");
}
return "dateView";
}
- 장점: 가장 간단하고 직관적인 방법.
- 단점: 매번 파싱 코드를 작성해야 하고, 에러 처리를 직접 해야 한다. 날짜 형식이 조금만 바뀌어도 코드를 수정해야 함.
2. @DateTimeFormat 어노테이션 사용 (권장):
- @DateTimeFormat 어노테이션을 사용하여 원하는 날짜/시간 형식을 지정.
- Spring이 자동으로 String을 java.time.LocalDate, java.time.LocalDateTime, java.util.Date 등으로 변환해 준다.
Java
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.util.Date;
@GetMapping("/date")
public String processDate(
@RequestParam("localDate") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate localDate,
@RequestParam("utilDate") @DateTimeFormat(pattern = "yyyy/MM/dd") Date utilDate,
@RequestParam("localDateTime") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime localDateTime,
Model model) {
model.addAttribute("localDate", localDate);
model.addAttribute("utilDate", utilDate);
model.addAttribute("localDateTime", localDateTime);
return "dateView";
}
* `pattern`: 사용할 날짜/시간 포맷을 지정합니다 (예: "yyyy-MM-dd", "MM/dd/yyyy", "yyyy-MM-dd HH:mm:ss").
* `iso`: ISO 8601 표준 포맷을 사용합니다 (예: `DateTimeFormat.ISO.DATE`, `DateTimeFormat.ISO.DATE_TIME`).
- 장점: 코드가 간결해지고, Spring이 자동으로 파싱과 에러 처리를 해준다. 다양한 날짜/시간 형식을 쉽게 지원.
- 단점: java.util.Date를 사용할 경우, 타임존 문제가 발생할 수 있으므로 주의. (가능하면 java.time 패키지의 클래스들을 사용하는 것이 좋다.)
3. @DateTimeFormat + java.time 패키지 (Java 8 이상, 가장 권장):
- Java 8부터 도입된 java.time 패키지 (LocalDate, LocalDateTime, ZonedDateTime 등)를 @DateTimeFormat과 함께 사용하는 것이 가장 좋다. java.time 패키지는 java.util.Date보다 훨씬 강력하고, 타임존 문제도 더 잘 처리 가능.
Java
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.springframework.format.annotation.DateTimeFormat;
@GetMapping("/date")
public String processDate(
@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date,
@RequestParam("dateTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime dateTime,
Model model) {
model.addAttribute("date", date);
model.addAttribute("dateTime", dateTime);
return "dateView";
}
4. Command Object (Form Object) 사용:
- 여러 개의 날짜 필드를 한 번에 받아야 하는 경우, Command Object (Form Object)를 사용하는 것이 좋다.
- Command Object는 @ModelAttribute 어노테이션과 함께 사용.
Java
//Controller
@PostMapping("/dateRange")
public String processDateRange(@ModelAttribute FormDate formDate, Model model) {
model.addAttribute("startDate", formDate.getStartDate());
model.addAttribute("endDate", formDate.getEndDate());
return "dateRangeView";
}
Java
//FormDate.java
import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
public class FormDate {
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate startDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate endDate;
// Getters and Setters
public LocalDate getStartDate() {
return startDate;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public LocalDate getEndDate() {
return endDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
}
5. 전역 설정 (Global Configuration):
- 모든 컨트롤러에서 동일한 날짜/시간 형식을 사용하고 싶다면, @ControllerAdvice와 @InitBinder를 사용하여 전역 설정을 할 수 있다. 하지만 @DateTimeFormat을 사용하는 것이 더 간편하고 유연하므로, 전역 설정은 꼭 필요한 경우에만 사용하는 것이 좋다.
Java
@ControllerAdvice
public class GlobalBindingInitializer {
@InitBinder
public void initBinder(WebDataBinder binder) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
binder.addCustomFormatter(new DateTimeFormatterRegistrar(dateFormatter));
//Java 8 이전
// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
}
정리 및 권장 사항:
- Java 8 이상: java.time 패키지 (LocalDate, LocalDateTime 등)와 @DateTimeFormat 어노테이션을 함께 사용하는 것이 가장 좋다.
- Java 7 이하: java.util.Date와 @DateTimeFormat 어노테이션을 사용하거나, String으로 받아서 SimpleDateFormat으로 직접 파싱. (타임존 문제에 주의)
- 여러 날짜 필드: Command Object (Form Object)를 사용하고, 각 필드에 @DateTimeFormat 어노테이션을 적용.
- URL Path Variable로 날짜 받기: @PathVariable과 @DateTimeFormat을 함께 사용할 수 있다.
Java
@GetMapping("/date/{date}")
public String processDateFromPath(@PathVariable("date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date, Model model) {
model.addAttribute("date", date);
return "dateview";
}