概要
営業日計算や帳票の日付処理で、日本の祝日を判定する必要は頻繁に生じます。しかし Java 標準 API には祝日カレンダーが含まれていないため、自前でリストを管理するか、外部データを取り込む仕組みが必要です。祝日法は改正されることがあり、春分の日・秋分の日は天文計算に基づくため、ハードコードだけでは運用が回らない場面も出てきます。この記事では、祝日データを定数リストとして管理しつつ、年ごとの更新を容易にする構成を紹介します。振替休日の自動算出ルールや、春分・秋分の近似計算、営業日ロジックへの接続方法も含め、実務でそのまま使える形に整えます。
使いどころ
年度ごとの祝日マスタを CSV から読み込み、営業日判定に使う
帳票の出力日が祝日に当たる場合に前営業日にスライドさせる
カレンダー表示で祝日に色を付ける処理のデータソースにする
コード例
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.util.ArrayList;
import java.util.List;
public class JapanHolidays {
// 固定日の祝日
public static List<LocalDate> getFixedHolidays(int year) {
return List.of(
LocalDate.of(year, Month.JANUARY, 1), // 元日
LocalDate.of(year, Month.FEBRUARY, 11), // 建国記念の日
LocalDate.of(year, Month.FEBRUARY, 23), // 天皇誕生日
LocalDate.of(year, Month.APRIL, 29), // 昭和の日
LocalDate.of(year, Month.MAY, 3), // 憲法記念日
LocalDate.of(year, Month.MAY, 4), // みどりの日
LocalDate.of(year, Month.MAY, 5), // こどもの日
LocalDate.of(year, Month.AUGUST, 11), // 山の日
LocalDate.of(year, Month.NOVEMBER, 3), // 文化の日
LocalDate.of(year, Month.NOVEMBER, 23) // 勤労感謝の日
);
}
// 第 n 月曜日を返す(Happy Monday 制度)
public static LocalDate nthMonday(int year, Month month, int n) {
var first = LocalDate.of(year, month, 1);
var offset = (DayOfWeek.MONDAY.getValue()
- first.getDayOfWeek().getValue() + 7) % 7;
return first.plusDays(offset + 7L * (n - 1));
}
// 固定日 + Happy Monday 祝日を結合
public static List<LocalDate> getHolidays(int year) {
var holidays = new ArrayList<>(getFixedHolidays(year));
holidays.add(nthMonday(year, Month.JANUARY, 2)); // 成人の日
holidays.add(nthMonday(year, Month.JULY, 3)); // 海の日
holidays.add(nthMonday(year, Month.SEPTEMBER, 3)); // 敬老の日
holidays.add(nthMonday(year, Month.OCTOBER, 2)); // スポーツの日
// 春分・秋分の近似計算、振替休日は省略
// 完全な実装は japan-holidays ツールを参照
holidays.sort(LocalDate::compareTo);
return holidays;
}
public static void main(String[] args) {
var holidays = getHolidays(2025);
holidays.forEach(h ->
System.out.println(h + " (" + h.getDayOfWeek() + ")")
);
}
}Version Coverage
Set.of() でイミュータブルな祝日セットを簡潔に初期化できる。var と toList() で記述量が減る。
// Java 17: Set.of() + var + Set.copyOf で簡潔に
var base = Set.of(
LocalDate.of(2024, 1, 1),
LocalDate.of(2024, 1, 8)
);
// 振替休日を追加してイミュータブルな Set を返す
var result = new TreeSet<>(base);
// ... 振替休日の追加処理 ...
return Set.copyOf(result);Library Comparison
注意点
春分の日・秋分の日は天文計算に基づくため、数年先の日付は暫定値になる。
祝日法の改正で祝日が追加・変更される可能性がある。
振替休日は「祝日が日曜に当たった場合、翌月曜が休日」というルール。
FAQ
内閣府の公開CSVを年初に取り込むバッチを組むのが現実的です。閣議決定で祝日が追加・移動されるため、自動取得の仕組みがあると安心です。
祝日が日曜なら翌月曜を振替休日とするルールをコードで表現できます。国民の祝日に関する法律第3条に基づく判定ロジックを実装します。
更新頻度が年1回程度なら定数管理で十分です。複数サービスで共有する場合や頻繁な変更がある場合はDB管理を検討します。