날짜와 시간 포맷팅과 파싱

실무에서 날짜와 시간을 다루다 보면 사용자에게 보여주기 위해 특정 형식으로 변환하거나, 반대로 사용자가 입력한 문자열을 날짜 객체로 변환해야 하는 경우가 빈번하다

핵심 개념

  • 포맷팅(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
M7, 07, Jul, July
d10
H시간(0-23)0, 13
h시간(1-12)1, 12
m30
s55
S밀리초978
a오전/오후AM,PM
E요일Tue, Tuesday

날짜와 시간의 포맷팅과 파싱은 실무에서 매우 자주 사용되는 기능이다. DateTimeFormatter를 제대로 이해하고 활용하면 사용자 친화적인 날짜 표시와 안정적인 날짜 입력 처리가 가능하다

출처 – 김영한 님의 강의 중 김영한의 실전 자바 – 중급 1편