概要
営業日の計算は、請求書の支払期日、納品日の算出、月次バッチのスケジュール管理など、業務システムで頻繁に必要になる処理です。Java 8 以降の LocalDate API を使えば、土日と祝日を除外しながら営業日を加減算するロジックを外部ライブラリなしで組み立てられます。この記事では、祝日リストとの突き合わせ、締日のスライド処理、月末営業日の判定といった実務で求められるパターンを整理し、再利用しやすいメソッドとして実装します。
使いどころ
請求書の支払期日を「発行日から5営業日後」として自動算出する
月次バッチの実行日を「毎月最終営業日」に設定する
納品予定日を土日祝を除いた営業日ベースで算出する
コード例
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.List;
import java.util.Set;
public class BusinessDayCalculator {
private static final Set<DayOfWeek> WEEKENDS =
Set.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
public static LocalDate addBusinessDays(
LocalDate start, int days, List<LocalDate> holidays) {
var current = start;
var remaining = days;
while (remaining > 0) {
current = current.plusDays(1);
if (!WEEKENDS.contains(current.getDayOfWeek())
&& !holidays.contains(current)) {
remaining--;
}
}
return current;
}
public static void main(String[] args) {
var holidays = List.of(
LocalDate.of(2025, 1, 1),
LocalDate.of(2025, 1, 13)
);
var start = LocalDate.of(2025, 1, 10);
var result = addBusinessDays(start, 3, holidays);
System.out.println(start + " から 3 営業日後: " + result);
}
}Version Coverage
Stream.iterate + datesUntil で営業日の抽出をストリームベースに記述できる。var で型宣言が簡潔になる。
// Java 17: Stream.iterate で営業日をフィルタ抽出
return Stream.iterate(from.plusDays(1), d -> d.plusDays(1))
.filter(d -> isBusinessDay(d, holidays))
.limit(n)
.reduce((first, last) -> last)
.orElseThrow();Library Comparison
注意点
祝日リストは年ごとに更新が必要。振替休日の判定ルールも考慮すること。
会社独自の休業日がある場合は、祝日リストに追加する仕組みが必要。
年末年始やお盆休みは祝日ではないため、別途ルールとして管理する。
FAQ
内閣府のCSVデータを年次で取り込むか、自前の定数テーブルで管理する方法が一般的です。祝日は法改正で変わるため、外部ソースからの定期取り込みが確実です。
除外判定のDayOfWeekリストからSATURDAYを外すだけで対応できます。判定条件を外部設定にしておくと業種ごとの切り替えも容易です。
祝日が連続する年末年始やGWの期間で境界値テストを行うのが効果的です。祝日と土日が重なるケースが最もずれやすいためです。