Java DateTimeFormatter クラス

DateTimeFormatter は、Java 8 で導入された日時 API(java.time パッケージ)における重要なクラスであり、日時オブジェクトのフォーマットと解析に使用されます。このクラスは、日時の表示と変換を処理する強力な機能を提供します。

簡単に言うと、DateTimeFormatter には主に2つの役割があります:

  • フォーマット:日時オブジェクト(LocalDate、LocalDateTime など)を特定の形式の文字列に変換します
  • 解析:形式に一致する文字列を日時オブジェクトに変換します

なぜ DateTimeFormatter が必要なのか

Java 8 より前では、日付のフォーマットと解析に SimpleDateFormat を使用していましたが、これにはいくつかの欠点がありました:

  • スレッドセーフではない
  • 設計がやや古い
  • エラー処理が不親切

DateTimeFormatter はこれらの問題を解決します:

  • スレッドセーフ:マルチスレッド環境で安全にインスタンスを共有できます
  • 不変:一度作成すると変更できません
  • より豊富な定義済み形式:多数の組み込み形式を提供します
  • より優れたエラー処理:解析に失敗した場合、より詳細なエラー情報を提供します

基本的な使用方法

定義済みフォーマッタ

DateTimeFormatter には、多くの定義済みフォーマット定数が用意されています:

例

LocalDateTime now = LocalDateTime.now();

// 定義済みフォーマッタを使用する
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE));     // 2023-11-15
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_TIME));     // 14:30:45.123
System.out.println(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); // 2023-11-15T14:30:45.123

カスタムパターン

パターン文字列を使用して、カスタムフォーマッタを作成できます:

例

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = now.format(formatter);  // フォーマット
System.out.println(formattedDateTime);             // 2023-11-15 14:30:45

// 解析
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-11-15 14:30:45", formatter);

// よく使われる中国語の日付形式
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
String formattedDate = today.format(chineseFormatter);
System.out.println("中国語形式の日付: " + formattedDate);

// 中国語の日付文字列を解析する
String chineseDateStr = "2023年05月20日";
LocalDate parsedDate = LocalDate.parse(chineseDateStr, chineseFormatter);
System.out.println("解析後の日付: " + parsedDate);

// その他のよく使われる形式
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/dd/yyyy");
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);

System.out.println("形式1: " + today.format(formatter1));
System.out.println("形式2: " + today.format(formatter2));
System.out.println("形式3(曜日付き): " + today.format(formatter3));

ローカライズ形式

さまざまなロケールに応じてフォーマッタを作成できます:

例

DateTimeFormatter frenchFormatter =
    DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
                     .withLocale(Locale.FRENCH);
String frenchDate = now.format(frenchFormatter);
System.out.println(frenchDate);  // 15 novembre 2023

パターン文字の説明

カスタム形式を作成する際は、特定のパターン文字を使用する必要があります:

文字 意味 例
y 年 yyyy → 2023
M 月 MM → 11
d 日 dd → 15
H 時(0-23) HH → 14
h 時(1-12) hh → 02
m 分 mm → 30
s 秒 ss → 45
S ミリ秒 SSS → 123
E 曜日 E → 水
a 午前/午後 a → 午後

ベストプラクティス

フォーマッタの再利用

DateTimeFormatter はスレッドセーフであるため、よく使うフォーマッタを定数として定義することをお勧めします:

例

public class DateUtils {
    public static final DateTimeFormatter STANDARD_FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
   
    // 使用方法
    String formatted = LocalDateTime.now().format(STANDARD_FORMATTER);
}

総合例:

例

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

public class サンプルTest {

    public static void main(String[] args) {
        // 1. LocalDate の例
        LocalDate currentDate = LocalDate.now();
        System.out.println(現在の日付: + currentDate);
       
        LocalDate specificDate = LocalDate.of(2023, 5, 20);
        System.out.println("特定の日付: " + specificDate);

        // 2. LocalTime の例
        LocalTime currentTime = LocalTime.now();
        System.out.println("現在の時刻: " + currentTime);
       
        LocalTime specificTime = LocalTime.of(14, 30, 15);
        System.out.println("特定の時刻: " + specificTime);

        // 3. LocalDateTime の例
        LocalDateTime currentDateTime = LocalDateTime.now();
        System.out.println(現在の日時: + currentDateTime);
       
        LocalDateTime specificDateTime = LocalDateTime.of(2023, 5, 20, 14, 30, 15);
        System.out.println("特定の日時: " + specificDateTime);

        // 4. DateTimeFormatter の例
        // 基本的なフォーマット
        DateTimeFormatter basicFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        System.out.println("基本フォーマット: " + currentDate.format(basicFormatter));

        // 中国語フォーマット
        DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日", Locale.CHINA);
        System.out.println("中国語の日付: " + currentDate.format(chineseFormatter));

        // 曜日付きの中国語フォーマット
        DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 EEEE", Locale.CHINA);
        System.out.println("曜日付きの中国語の日付: " + currentDate.format(weekFormatter));

        // 時刻のフォーマット
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH时mm分ss秒");
        System.out.println("中国語の時刻: " + currentTime.format(timeFormatter));

        // 日時のフォーマット
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println("標準の日時: " + currentDateTime.format(dateTimeFormatter));

        // 日付の解析
        String dateStr = "2023-05-20";
        LocalDate parsedDate = LocalDate.parse(dateStr, basicFormatter);
        System.out.println("解析後の日付: " + parsedDate);

        // 中国語の日付を解析する
        String chineseDateStr = "2023年05月20日";
        LocalDate parsedChineseDate = LocalDate.parse(chineseDateStr, chineseFormatter);
        System.out.println("解析後の中国語の日付: " + parsedChineseDate);
    }
}

出力結果は次のとおりです:

当前日期: 2025-05-01
特定日期: 2023-05-20
当前时间: 10:46:38.591747
特定时间: 14:30:15
当前日期时间: 2025-05-01T10:46:38.592002
特定日期时间: 2023-05-20T14:30:15
基本格式化: 2025-05-01
中文日期: 2025年05月01日
带星期的中文日期: 2025年05月01日 星期四
中文时间: 10时46分38秒
标准日期时间: 2025-05-01 10:46:38
解析后的日期: 2023-05-20
解析后的中文日期: 2023-05-20

解析例外の処理

文字列を解析する際は、発生する可能性のある例外を処理する必要があります:

例

try {
    LocalDateTime dateTime = LocalDateTime.parse("2023-11-15", formatter);
} catch (DateTimeParseException e) {
    System.err.println("日時を解析できません: " + e.getMessage());
}

タイムゾーンの考慮

タイムゾーンを処理する必要がある場合は、ZonedDateTimeおよび特定のタイムゾーンパターンを使用できます:

例

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime.format(formatter));  // 2023-11-15 14:30:45 CST

まとめ

DateTimeFormatter は、Java 8 の日時 API においてフォーマットと解析を処理する強力なツールです。旧来の SimpleDateFormat と比較して、より安全で、柔軟性が高く、使いやすくなっています。DateTimeFormatter の使い方を習得することで、さまざまな日時形式のニーズをより効率的に処理できます。

重要なポイントを覚えておきましょう:

  • 定義済みフォーマッタを使用して一般的な形式を処理する
  • ofPattern() を使用してカスタム形式を作成する
  • ローカライズとタイムゾーンの要件を考慮する
  • スレッドセーフなフォーマッタインスタンスを再利用する
  • 解析例外を適切に処理する
その他の拡張