CodeGym /행동 /JAVA 25 SELF /날짜 포매팅과 파싱: DateTimeFormatter

날짜 포매팅과 파싱: DateTimeFormatter

JAVA 25 SELF
레벨 13 , 레슨 4
사용 가능

1. DateTimeFormatter: 무엇이며 왜 필요한가

실제 프로그램에서 날짜는 코드 내부에만 존재하지 않습니다. 보통 다음이 필요합니다:

  • 문자열로 변환해 콘솔, 화면, 파일 등에 출력하기(예: "01.06.2025 14:30").
  • 문자열을 파싱해, 사용자 입력이나 파일에서 온 문자열을 다시 날짜/시간 객체로 되돌리기.

이를 위해 Java에는 강력하고 편리한 도구 — java.time.format.DateTimeFormatter 클래스가 있습니다.

DateTimeFormatter는 시간 객체(LocalDate, LocalDateTime, ZonedDateTime, Instant 등)와 문자열 사이를 이어 주는 “번역기”라고 할 수 있습니다. 할 수 있는 일은 다음과 같습니다:

  • 날짜/시간 객체를 원하는 형식의 문자열로 변환(format — 포매팅).
  • 문자열을 날짜/시간 객체로 변환(parse — 파싱).

2. 표준 포매터: 빠르고 간편하게

Java는 가장 대중적인 ISO 형식(날짜와 시간에 대한 국제 표준)을 다루는 표준 포매터들을 이미 준비해 두었습니다.

그중 일부는 다음과 같습니다:

포매터 문자열 예 설명
DateTimeFormatter.ISO_LOCAL_DATE
2025-06-01 날짜만 (년-월-일)
DateTimeFormatter.ISO_LOCAL_TIME
14:30:00 시간만 (시:분:초)
DateTimeFormatter.ISO_LOCAL_DATE_TIME
2025-06-01T14:30:00 시간대 없는 날짜와 시간
DateTimeFormatter.ISO_ZONED_DATE_TIME
2025-06-01T14:30:00+03:00[Europe/Minsk] 날짜, 시간 및 시간대

표준 포매터 사용 예

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class FormatterDemo {
    public static void main(String[] args) {
        LocalDate date = LocalDate.now();
        // 날짜를 문자열로 포매팅
        String text = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(text); // 예: 2025-06-01

        // 문자열을 다시 날짜로 파싱
        LocalDate parsed = LocalDate.parse("2025-06-01", DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(parsed); // 2025-06-01
    }
}

비유

만약 Java가 커피숍이라면, 표준 포매터는 “아메리카노”, “라떼”, “에스프레소”와 같습니다. 빠르고 표준적이지만, 때로는 특별한 무언가가 필요하죠!

3. 사용자 지정 패턴: DateTimeFormatter.ofPattern

가끔 표준 형식만으로는 부족합니다. 예를 들어 "01.06.2025 14:30"처럼 출력해야 할 때가 있고, "2025-06-01T14:30:00"은 원치 않을 수 있습니다. 이럴 때 DateTimeFormatter.ofPattern(String pattern) 메서드로 원하는 패턴을 만들 수 있습니다.

패턴 문법

패턴에는 다음과 같은 특수 문자를 사용합니다:

  • y — 연도 (yyyy2025)
  • M — 월 (MM06)
  • d — 일 (dd01)
  • H — 시 (24시간제, HH14)
  • m — 분 (mm30)
  • s — 초 (ss00)

패턴 예시

패턴 결과 예
"dd.MM.yyyy"
01.06.2025
"yyyy/MM/dd"
2025/06/01
"dd.MM.yyyy HH:mm"
01.06.2025 14:30
"yyyy-MM-dd HH:mm:ss"
2025-06-01 14:30:00
"d MMMM yyyy"
1 iyunya 2025 (ru 로케일에서)

예: 날짜와 시간 포매팅

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class CustomFormatDemo {
    public static void main(String[] args) {
        LocalDateTime dt = LocalDateTime.of(2025, 6, 1, 14, 30);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
        String text = dt.format(formatter);
        System.out.println(text); // 01.06.2025 14:30
    }
}

예: 문자열을 날짜로 파싱

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class ParseDemo {
    public static void main(String[] args) {
        String input = "01.06.2025 14:30";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
        LocalDateTime dt = LocalDateTime.parse(input, formatter);
        System.out.println(dt); // 2025-06-01T14:30
    }
}

주의: 패턴은 문자열과 정확히 일치해야 합니다! 문자열에 초가 있다면 패턴에 :ss를 추가하세요.

4. 포매팅: 날짜/시간을 문자열로 변환

일반 절차

  1. LocalDate, LocalDateTime, ZonedDateTime 등 필요한 객체를 만든다.
  2. 필요한 포매터를 만들거나 선택한다.
  3. 객체의 format(DateTimeFormatter) 메서드를 호출해 문자열을 얻는다.

예: 여러 형식으로 날짜 출력

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class MultiFormatDemo {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2025, 6, 1);

        // 표준 ISO
        System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2025-06-01

        // 사용자 지정 형식
        DateTimeFormatter rusFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        System.out.println(date.format(rusFormat)); // 01.06.2025

        // 영어 스타일
        DateTimeFormatter usFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy");
        System.out.println(date.format(usFormat)); // 06/01/2025
    }
}

시간 포매팅

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class TimeFormatDemo {
    public static void main(String[] args) {
        LocalTime time = LocalTime.of(14, 30, 5);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        System.out.println(time.format(formatter)); // 14:30:05
    }
}

5. 파싱: 문자열을 날짜/시간으로 변환

일반 절차

  1. 문자열을 받는다(예: 사용자 입력).
  2. 문자열과 동일한 패턴의 포매터를 생성한다.
  3. 정적 메서드 parse() 또는 포매터 객체의 parse() 메서드를 호출한다.

예: 날짜 파싱

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class ParseDateDemo {
    public static void main(String[] args) {
        String input = "01.06.2025";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        LocalDate date = LocalDate.parse(input, formatter);
        System.out.println(date); // 2025-06-01
    }
}

예: 날짜와 시간 파싱

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class ParseDateTimeDemo {
    public static void main(String[] args) {
        String input = "01.06.2025 14:30";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
        LocalDateTime dateTime = LocalDateTime.parse(input, formatter);
        System.out.println(dateTime); // 2025-06-01T14:30
    }
}

6. 파싱 오류 처리

파싱은 까다로울 수 있습니다. 문자열이 패턴과 맞지 않으면 Java는 DateTimeParseException 예외를 던집니다. 이는 사용자가 잘못된 날짜를 입력한 경우처럼 흔한 상황입니다.

예: 파싱 시 오류 처리

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class ParseErrorDemo {
    public static void main(String[] args) {
        String input = "32.13.2025"; // 잘못된 날짜
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        try {
            LocalDate date = LocalDate.parse(input, formatter);
            System.out.println(date);
        } catch (DateTimeParseException ex) {
            System.out.println("파싱 오류: " + ex.getMessage());
        }
    }
}

중요: 사용자 입력을 다룰 때에는 반드시 이러한 오류를 처리하세요!

7. 실습: 사용자용 날짜 변환

예를 들어, 학습용 애플리케이션에서 다음과 같은 작업이 있다고 합시다. 사용자가 "dd.MM.yyyy" 형식으로 생년월일을 입력하면, 프로그램은 이를 "yyyy/MM/dd" 형식으로 출력하고 요일까지 보여줘야 합니다.

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Scanner;

public class BirthdayFormatDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("생년월일을 입력하세요 (dd.MM.yyyy): ");
        String input = scanner.nextLine();

        DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        try {
            LocalDate birthday = LocalDate.parse(input, inputFormat);
            String formatted = birthday.format(outputFormat);
            System.out.println("새 형식의 날짜: " + formatted);
            System.out.println("요일: " + birthday.getDayOfWeek()); // 예: SATURDAY
        } catch (DateTimeParseException ex) {
            System.out.println("오류: 잘못된 날짜 형식입니다!");
        }
    }
}

8. 현지화: 언어가 포매팅에 미치는 영향

DateTimeFormatter를 사용하면 숫자 순서만 바꾸는 것이 아니라 월 이름, 요일 등도 단어로 출력할 수 있습니다. 이때 로케일(언어와 지역 설정)이 반영됩니다.

예: 러시아어로 월을 글자로 출력

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class LocaleDemo {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2025, 6, 1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", new Locale("ru"));
        System.out.println(date.format(formatter)); // 1 iyunya 2025
    }
}

예: 영어 로케일

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class LocaleEnDemo {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2025, 6, 1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.ENGLISH);
        System.out.println(date.format(formatter)); // 1 June 2025
    }
}

팁: 월이나 요일을 원하는 언어로 출력하려면 로케일을 명시적으로 지정하세요!

9. 날짜 포매팅/파싱에서 흔한 실수

실수 № 1: 패턴과 문자열이 일치하지 않음.
문자열이 "01.06.2025 14:30"인데 패턴이 "dd.MM.yyyy"라면 파싱은 실패합니다. 패턴은 문자열과 정확히 일치해야 합니다.

실수 № 2: 패턴 문자를 혼동함.
MM은 월, mm은 분입니다. "dd.mm.yyyy"처럼 작성하면 Java는 분을 의미한다고 판단해 오류가 발생합니다. 월에는 항상 대문자 M을 사용하세요.

실수 № 3: 파싱 예외를 처리하지 않음.
DateTimeParseException을 잡지 않으면, 잘못된 사용자 입력으로 프로그램이 갑자기 종료될 수 있습니다. 반드시 이런 예외를 처리하세요.

실수 № 4: 단어를 사용할 때 로케일을 지정하지 않음.
월을 글자로 출력하는 패턴(MMMM)을 쓰면서 로케일을 지정하지 않으면, Java는 기본 언어(예: 영어)를 사용할 수 있습니다. 항상 필요한 로케일을 명시적으로 지정하세요.

실수 № 5: 구식 클래스(SimpleDateFormat, Date)를 새 프로젝트에서 사용함.
기억하세요: 현대 코드에서는 java.timeDateTimeFormatter만 사용하세요.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION