概要
和暦の基本的な変換は JapaneseDate と DateTimeFormatter で対応できますが、実務ではもう少し踏み込んだ要件に直面します。「R6」「H30」のような英字略称から西暦への変換、元号境界をまたぐ日付の正確な判定、帳票向けの「元年」表記、そして元号を型安全に扱うための設計パターンなどです。この記事では、wareki-conversion で扱った基本変換の先にある実務的な要件を掘り下げ、Java 17 の switch 式や Java 21 の sealed interface / pattern matching を活用した堅牢な実装を紹介します。
使いどころ
金融系帳票で「R6」「H30」のような SHR 英字略称を西暦年に変換する
元号の境界日(2019/5/1 など)をまたぐ期間を正確に計算する
和暦を sealed interface で型安全にモデル化し、元号ごとの処理分岐を網羅的に書く
コード例
import java.time.LocalDate;
public class JapaneseEraDetailed {
private static final int REIWA_BASE = 2018;
private static final int HEISEI_BASE = 1988;
private static final int SHOWA_BASE = 1925;
private static final int TAISHO_BASE = 1911;
public static String toWareki(LocalDate date) {
var jDate = JapaneseDate.from(date);
var eraFmt = DateTimeFormatter.ofPattern(
"GGGG", Locale.JAPANESE);
var eraName = eraFmt.format(jDate);
int year = jDate.get(ChronoField.YEAR_OF_ERA);
return (year == 1)
? eraName + "元年"
: eraName + year + "年";
}
public static int abbreviationToSeireki(String abbrev) {
if (abbrev == null || abbrev.length() < 2) {
throw new IllegalArgumentException(
"不正な略称: " + abbrev);
}
char era = Character.toUpperCase(abbrev.charAt(0));
int japYear = Integer.parseInt(abbrev.substring(1));
int base = switch (era) {
case 'R' -> REIWA_BASE;
case 'H' -> HEISEI_BASE;
case 'S' -> SHOWA_BASE;
case 'T' -> TAISHO_BASE;
default -> throw new IllegalArgumentException(
"不明な元号: " + era);
};
return base + japYear;
}
public static void main(String[] args) {
System.out.println(toWareki(LocalDate.of(2025, 3, 27)));
System.out.println(toWareki(LocalDate.of(2019, 5, 1)));
System.out.println(toWareki(LocalDate.of(2019, 4, 30)));
System.out.println("R7 -> " + abbreviationToSeireki("R7"));
System.out.println("H30 -> " + abbreviationToSeireki("H30"));
System.out.println("S64 -> " + abbreviationToSeireki("S64"));
}
}Version Coverage
switch 式で SHR略称や元号名の分岐が簡潔に書ける。fall-through がなく、値を直接返せる。
// Java 17: switch 式で簡潔に記述
int base = switch (era) {
case 'R' -> REIWA_BASE;
case 'H' -> HEISEI_BASE;
case 'S' -> SHOWA_BASE;
case 'T' -> TAISHO_BASE;
default -> throw new IllegalArgumentException(
"不明な元号: " + era);
};
return base + japYear;Library Comparison
注意点
SHR略称の変換は年レベルの簡易方式。月日をまたぐ正確な境界判定が必要な場合は JapaneseDate 方式を使うこと
JapaneseDate は明治6年(1873年)以降のみ対応。それ以前の日付を渡すと DateTimeException が発生する
DateTimeFormatter の和暦パターンで G の数は表示名の長さを制御する。GGGG で「令和」、G で「令」のように変わる
sealed interface で元号を型安全に表現する場合、新しい元号の追加時にはコンパイルエラーで漏れを検出できるが、permits 宣言の更新が必要になる
FAQ
公式規格ではなく慣例です。金融や行政の帳票で広く使われていますが、システムごとに確認が必要です。
新しい元号が追加されたとき、permits 宣言を更新すれば switch 文の網羅漏れをコンパイルエラーで検出できます。
toWareki メソッドの year == 1 判定を外すだけで対応できます。帳票仕様に合わせて切り替えてください。