CodeGym /コース /JAVA 25 SELF /日付のフォーマットとパース: DateTimeFormatter

日付のフォーマットとパース: DateTimeFormatter

JAVA 25 SELF
レベル 13 , レッスン 4
使用可能

1. DateTimeFormatter: 何で、何のために使うのか

実際のプログラムでは、日付はコードの中だけで完結することはほとんどありません。通常は次のことが必要になります:

  • 文字列に変換してコンソール、画面、またはファイルに出力する(例: "01.06.2025 14:30")。
  • 文字列をパースし、ユーザーが入力したりファイルから来た文字列を日付/時刻オブジェクトに戻す。

そのために Java には強力で使いやすいツール — クラス java.time.format.DateTimeFormatter があります。

DateTimeFormatter は、時間のオブジェクト(LocalDateLocalDateTimeZonedDateTimeInstant など)と文字列の間の「翻訳者」だと言えます。できること:

  • 日付/時刻オブジェクトを、必要な形式の文字列に変換する(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(ロシア語ロケールの場合)

例: 日付と時刻のフォーマット

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. 必要なオブジェクト(LocalDateLocalDateTimeZonedDateTime など)を作成する。
  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: 古いクラス(SimpleDateFormatDate)を新しいプロジェクトで使う。
覚えておきましょう: 現代的なコードでは java.timeDateTimeFormatter を使います。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION