概要
帳票の日付欄、ログのタイムスタンプ、CSV の日付カラムなど、日付を特定の文字列形式に変換する処理は業務コードの至るところにあります。Java 8 以降は DateTimeFormatter がスレッドセーフなフォーマッタとして使えるため、従来の SimpleDateFormat で起きていたマルチスレッドの事故を回避できます。この記事では、DateTimeFormatter によるフォーマットの基本から、日本語ロケールでの曜日表示、ISO 8601 形式の出力、そして SimpleDateFormat からの移行指針までを整理します。
使いどころ
帳票の日付欄を「2025年03月27日(木)」のような日本語形式で出力する
ログファイルのタイムスタンプを「yyyy-MM-dd HH:mm:ss」で統一する
CSV 出力時の日付カラムを「yyyy/MM/dd」形式に揃える
コード例
import java.time.LocalDate;
public class DateFormatting {
private static final DateTimeFormatter YMD =
DateTimeFormatter.ofPattern("yyyy/MM/dd");
private static final DateTimeFormatter FULL_JP =
DateTimeFormatter.ofPattern(
"yyyy年MM月dd日(EEE) HH:mm", Locale.JAPANESE);
public static void main(String[] args) {
var today = LocalDate.of(2025, 3, 27);
System.out.println("スラッシュ: " + today.format(YMD));
var now = LocalDateTime.now();
System.out.println("日本語: " + now.format(FULL_JP));
System.out.println("ISO: " +
today.format(DateTimeFormatter.ISO_LOCAL_DATE));
var parsed = LocalDate.parse("2025/03/27", YMD);
System.out.println("パース結果: " + parsed);
}
}Version Coverage
テキストブロック(Java 15+)でフォーマットパターン文字列を読みやすく定義できる。DateTimeFormatter 自体の API に変化はない。
// Java 17: DateTimeFormatter(スレッドセーフ)
private static final DateTimeFormatter DTF =
DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formatted = LocalDate.now().format(DTF);Library Comparison
注意点
SimpleDateFormat はスレッドアンセーフ。マルチスレッド環境で共有するとフォーマット結果が壊れる。DateTimeFormatter へ移行するのが安全
DateTimeFormatter.ofPattern の月は MM(2桁ゼロ埋め)と M(ゼロ埋めなし)で異なる。帳票仕様に合わせて使い分けること
曜日を日本語で表示するには Locale.JAPANESE を明示する。指定しないと JVM のデフォルトロケールに依存する
DateTimeFormatter は不変オブジェクトのため、static final フィールドで定義して使い回すのが定石
FAQ
新規コードは DateTimeFormatter に統一し、既存コードは影響範囲を見て段階的に置き換えるのが現実的です。
M は月、m は分、H は24時間制の時、h は12時間制の時です。混同するとパース時に例外になります。
DateTimeFormatter は不変でスレッドセーフなので、static final で共有するのが推奨パターンです。