실무에서 날짜와 시간을 다루다 보면 사용자에게 보여주기 위해 특정 형식으로 변환하거나, 반대로 사용자가 입력한 문자열을 날짜 객체로 변환해야 하는 경우가 빈번하다
핵심 개념
- 포맷팅(Formatting): 날짜와 시간 객체를 원하는 형식의 문자열로 변환
- 파싱(Parsing): 문자열을 날짜와 시간 객체로 변환
포맷팅은 날짜/시간 객체 → 문자열, 파싱은 문자열 → 날짜/시간 객체 변환이다
날짜 포맷팅과 파싱 (LocalDate)
기본 출력의 한계
LocalDate date = LocalDate.of(2024, 12, 31);
System.out.println("date = " + date);
// 출력: date = 2024-12-31
LocalDate를 그냥 출력하면 ISO 8601 표준 형식(yyyy-MM-dd)으로 출력된다. 하지만 한국 사용자에게는 “2024년 12월 31일” 형식이 더 친숙하다
DateTimeFormatter를 이용한 포맷팅
public class FormattingMain1 {
public static void main(String[] args) {
// 포맷팅: 날짜를 문자로
LocalDate date = LocalDate.of(2024, 12, 31);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일");
String formattedDate = date.format(formatter);
System.out.println("날짜 포맷팅: " + formattedDate);
// 출력: 날짜 포맷팅: 2024년 12월 31일
// 파싱: 문자를 날짜로
String input = "2030년 01월 01일";
LocalDate parsedDate = LocalDate.parse(input, formatter);
System.out.println("문자열 파싱 결과: " + parsedDate);
// 출력: 문자열 파싱 결과: 2030-01-01
}
}
핵심 포인트
- DateTimeFormatter.ofPattern()으로 원하는 패턴 정의
- date.format(formatter)로 날짜 → 문자열 변환
- LocalDate.parse(input, formatter)로 문자열 → 날짜 변환
- 패턴의 형식과 입력 문자열의 형식이 정확히 일치해야 한다
주의사항 – 대소문자 구분
// 올바른 사용 "yyyy년 MM월 dd일" // MM: 월(Month), dd: 일(day) // 잘못된 사용 "yyyy년 mm월 dd일" // mm: 분(minute) - 잘못됨
- MM(대문자): 월(Month)
- mm(소문자): 분(minute)
- dd(소문자): 일(day)
- DD(대문자): 연중 일수 (Day of year)
날짜와 시간 포맷팅과 파싱 (LocalDateTime)
시간까지 포함한 포맷팅
public class FormattingMain2 {
public static void main(String[] args) {
// 포맷팅: 날짜와 시간을 문자로
LocalDateTime now = LocalDateTime.of(2024, 12, 31, 13, 30, 59);
System.out.println("기본 출력: " + now);
// 출력: 기본 출력: 2024-12-31T13:30:59
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = now.format(formatter);
System.out.println("날짜와 시간 포맷팅: " + formattedDateTime);
// 출력: 날짜와 시간 포맷팅: 2024-12-31 13:30:59
// 파싱: 문자를 날짜와 시간으로
String dateTimeString = "2030-01-01 11:30:00";
LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println("문자열 파싱 결과: " + parsedDateTime);
// 출력: 문자열 파싱 결과: 2030-01-01T11:30
}
}
시간 패턴의 이해
// 24시간제 "yyyy-MM-dd HH:mm:ss" // HH: 0-23 시간 // 12시간제 (오전/오후) "yyyy-MM-dd hh:mm:ss a" // hh: 1-12 시간, a: AM/PM
- HH (대문자): 24시간제(0-23)
- hh (소문자): 12시간제(1-12)
- a: 오전/오후 마커(AM/PM)
실무에서 자주 사용하는 패턴
날짜 패턴
// ISO 8601 표준 (API 통신에 많이 사용) "yyyy-MM-dd" // 2024-12-31 // 한국식 표기 "yyyy년 MM월 dd일" // 2024년 12월 31일 // 파일명용 "yyyyMMdd" // 20241231 // 요일 포함 "yyyy-MM-dd (E)" // 2024-12-31 (화) "yyyy년 MM월 dd일 EEEE" // 2024년 12월 31일 화요일
날짜와 시간 패턴
// 데이터베이스 표준 "yyyy-MM-dd HH:mm:ss" // 2024-12-31 13:30:59 // ISO 8601 확장 "yyyy-MM-dd'T'HH:mm:ss" // 2024-12-31T13:30:59 // 한국식 (12시간제) "yyyy년 MM월 dd일 a hh:mm" // 2024년 12월 31일 오후 01:30 // 로그 파일용 (밀리초 포함) "yyyy-MM-dd HH:mm:ss.SSS" // 2024-12-31 13:30:59.123
실무에서 사용하는 베스트 프랙티스
Formatter 재사용
// 매번 생성 X
public String formatDate(LocalDate date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
return date.format(formatter);
}
// static final로 재사용
public class DateUtil {
private static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd");
public static String formatDate(LocalDate date) {
return date.format(DATE_FORMATTER);
}
}
DateTimeFormatter는 불변(immutable)이며 스레드 안전(thread-safe)하므로 재사용이 권장된다
파싱 예외 처리
public LocalDate parseDate(String dateString) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
try {
return LocalDate.parse(dateString, formatter);
} catch (DateTimeParseException e) {
// 로깅 및 적절한 예외 처리
throw new IllegalArgumentException("잘못된 날짜 형식입니다: " + dateString, e);
}
}
미리 정의된 포매터 활용
Java는 자주 사용하는 포맷을 미리 정의해두었다
// ISO 날짜 LocalDate.now().format(DateTimeFormatter.ISO_DATE); // 2024-12-31 // ISO 날짜와 시간 LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME); // 2024-12-31T13:30:59 // RFC 1123 (HTTP 날짜 헤더) ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME); // Tue, 31 Dec 2024 13:30:59 GMT
DateTimeFormatter 패턴 레퍼런스
| 기호 | 의미 | 예시 |
| y | 연도 | 2025, 24 |
| M | 월 | 7, 07, Jul, July |
| d | 일 | 10 |
| H | 시간(0-23) | 0, 13 |
| h | 시간(1-12) | 1, 12 |
| m | 분 | 30 |
| s | 초 | 55 |
| S | 밀리초 | 978 |
| a | 오전/오후 | AM,PM |
| E | 요일 | Tue, Tuesday |
날짜와 시간의 포맷팅과 파싱은 실무에서 매우 자주 사용되는 기능이다. DateTimeFormatter를 제대로 이해하고 활용하면 사용자 친화적인 날짜 표시와 안정적인 날짜 입력 처리가 가능하다