CRON解析とは何をするものか
CRON解析とは、
「0 0 * * * のような CRON 表記を読み取り、次にいつ実行されるかを計算する」
「この CRON は毎日? 毎週? 毎月? どんなタイミングで動くのかを理解する」
といった“スケジュールの意味を解釈する”処理のことです。
業務システムでは、バッチ処理、定期メンテナンス、ログローテーション、外部APIの定期取得など、
CRON 形式でスケジュールを指定する場面が非常に多いです。
CRON解析ユーティリティを作っておくと、
「次の実行時刻を計算する」「設定ミスを検出する」「スケジュールの説明を表示する」
といった処理が簡単になります。
CRON の基本構造を理解する
5フィールド(UNIX系の標準CRON)
一般的な CRON は次の5つのフィールドで構成されます。
分 時 日 月 曜日
例:0 3 * * * → 毎日 03:00*/5 * * * * → 5分ごと0 0 1 * * → 毎月1日の 00:000 9 * * 1-5 → 平日 09:00
Java で CRON を扱うときは、
「この文字列を解析して、次の実行時刻を計算する」
という処理が中心になります。
Java で CRON を解析する方法
Java 標準には CRON パーサーがない
Java 標準 API (java.time) には CRON を直接解析する機能はありません。
そのため、実務では次のどちらかを選びます。
- 自分で CRON 解析ユーティリティを書く
- ライブラリ(Quartz など)を使う
ここでは「自作ユーティリティで CRON を解析する」ことにフォーカスします。
初心者でも理解できるよう、まずは「簡易 CRON(分・時のみ)」から始めて、
徐々に本格的な CRON に近づけていきます。
まずは「分・時」だけの簡易 CRON を解析する
例:"0 3" → 毎日 03:00
import java.time.LocalDateTime;
import java.time.LocalTime;
public class SimpleCronParser {
public static LocalDateTime nextRun(String cron) {
String[] parts = cron.split(" ");
int minute = Integer.parseInt(parts[0]);
int hour = Integer.parseInt(parts[1]);
LocalDateTime now = LocalDateTime.now();
LocalDateTime todayRun = now.withHour(hour).withMinute(minute).withSecond(0).withNano(0);
if (now.isBefore(todayRun)) {
return todayRun;
} else {
return todayRun.plusDays(1);
}
}
}
Java使い方:
LocalDateTime next = SimpleCronParser.nextRun("0 3");
System.out.println("次の実行: " + next);
Javaここで深掘りしたいのは、
「今日の実行時刻が過ぎていたら、明日に回す」
というロジックです。
これは CRON 解析の基本中の基本で、
どんな複雑な CRON でも、この考え方が土台になります。
「*/5」などのステップ表記を解析する
例:*/5 → 5分ごと
CRON のステップ表記は、
「0,5,10,15,20…」のように一定間隔の値を意味します。
public class CronStep {
public static int nextStepValue(int current, int step) {
return ((current / step) + 1) * step;
}
}
Java例:
int next = CronStep.nextStepValue(7, 5); // 7分の次は10分
System.out.println(next);
Javaこの「ステップ計算」は、
CRON の「/5」「/10」「*/30」などを解析するうえで必須のテクニックです。
本格的な CRON(分・時・日・月・曜日)を解析する
CRON の各フィールドを「候補値の集合」として扱う
CRON 解析の本質は、
「各フィールドを“許可された値の集合”として扱う」
という考え方です。
例:0 9 * * 1-5(平日9時)
分 → {0}
時 → {9}
日 → {1〜31}
月 → {1〜12}
曜日 → {1,2,3,4,5}
この「集合」を使って、
「現在時刻より後で、最も近い組み合わせ」を探すのが CRON 解析です。
例:曜日フィールドの解析
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CronFieldParser {
public static Set<Integer> parseRange(String field) {
if (field.equals("*")) {
return IntStream.rangeClosed(0, 6).boxed().collect(Collectors.toSet());
}
if (field.contains("-")) {
String[] parts = field.split("-");
int start = Integer.parseInt(parts[0]);
int end = Integer.parseInt(parts[1]);
return IntStream.rangeClosed(start, end).boxed().collect(Collectors.toSet());
}
return Set.of(Integer.parseInt(field));
}
}
Java例:
Set<Integer> weekdays = CronFieldParser.parseRange("1-5");
System.out.println(weekdays); // [1,2,3,4,5]
Javaここで深掘りしたいのは、
「CRON は“値の集合”として扱うと理解しやすい」
という点です。
CRON 解析の最重要ポイント:次の実行時刻の探索
「秒 → 分 → 時 → 日 → 月 → 年」の順に繰り上げる
CRON 解析の本質は、
「現在時刻から未来に向かって、条件を満たす最初の日時を探す」
という処理です。
これは、時計の針を進めるように、
秒が合わなければ次の秒
分が合わなければ次の分
時が合わなければ次の時
日が合わなければ次の日
月が合わなければ次の月
という順番で繰り上げていきます。
この考え方を理解すると、
CRON 解析のロジックが一気にクリアになります。
CRON解析ユーティリティの完成形(簡易版)
「次の実行時刻」を返すユーティリティ
以下は、分・時・曜日に対応した簡易 CRON 解析の例です。
import java.time.*;
import java.util.Set;
public class SimpleCronScheduler {
private final Set<Integer> minutes;
private final Set<Integer> hours;
private final Set<Integer> weekdays;
public SimpleCronScheduler(Set<Integer> minutes, Set<Integer> hours, Set<Integer> weekdays) {
this.minutes = minutes;
this.hours = hours;
this.weekdays = weekdays;
}
public LocalDateTime nextRun(LocalDateTime now) {
LocalDateTime t = now.plusMinutes(1).withSecond(0).withNano(0);
while (true) {
if (minutes.contains(t.getMinute()) &&
hours.contains(t.getHour()) &&
weekdays.contains(t.getDayOfWeek().getValue())) {
return t;
}
t = t.plusMinutes(1);
}
}
}
Java使い方:
SimpleCronScheduler scheduler =
new SimpleCronScheduler(
Set.of(0), // 分
Set.of(9), // 時
Set.of(1,2,3,4,5) // 平日
);
LocalDateTime next = scheduler.nextRun(LocalDateTime.now());
System.out.println("次の実行: " + next);
Javaこのように、
「CRON を解析して、次の実行時刻を返す」
という処理をユーティリティ化しておくと、
スケジューラの安定性が大きく向上します。
セキュリティ・運用の観点から見た CRON解析
CRON の誤設定は“障害”につながる
CRON の設定ミスは、次のような重大な問題を引き起こします。
・バッチが重複実行される
・外部APIを短時間に叩きすぎてレート制限に引っかかる
・バックアップが重なってシステムが重くなる
・ログローテーションがずれてディスクが埋まる
CRON解析ユーティリティを使って、
「設定が正しいか」「次の実行時刻が妥当か」を検証することは、
セキュリティと運用の両面で非常に重要です。
タイムゾーンを意識しないと危険
CRON は「ローカルタイム」で動くことが多いため、
サマータイムのある地域では「存在しない時刻」「重複する時刻」が発生します。
Java の ZonedDateTime を使えば、
こうした“時間の歪み”を安全に扱えます。
まとめ:CRON解析で身につけてほしい感覚
CRON解析は、単なる文字列処理ではありません。
「時間の集合を扱い、未来の実行時刻を探索する」という、
業務システムに欠かせない重要な技術です。
CRON は「値の集合」として扱う。
次の実行時刻は「未来に向かって探索する」。
ステップ表記(*/5)や範囲(1-5)は集合に展開する。
スケジューラのズレは障害につながるため、CRON解析は非常に重要。
タイムゾーンやサマータイムも考慮する。
もしあなたのプロジェクトで、
「CRON の意味が分からない」「次の実行時刻がズレる」
といった問題があるなら、
まずは今回の CRON解析ユーティリティを導入してみてください。
スケジュールの安定性が大きく向上し、
運用トラブルの予防にもつながります。
