Cron Expression Basics - cron式の書き方と読み方
0 3 * * * のような文字列を見て、いつ実行されるのか即座に読めるでしょうか。cron expression(cron式)は5つのフィールドと数種類の特殊文字だけで あらゆるスケジュールを表現できる非常にコンパクトな書式ですが、日フィールドと曜日フィールドの 関係など直感に反する仕様もあります。この記事ではcron式の基本文法から、よく使うパターン早見表、 6フィールド版との違いまでを整理します。
A cron expression packs an entire recurring schedule into five space-separated fields. This guide walks through what each field means, how the special characters (* , - /) combine, a lookup table of common patterns, and the gotchas around day-of-month vs. day-of-week and 6-field (seconds-included) variants like Quartz.
TL;DR
- 標準cronは分 時 日 月 曜日の5フィールド。左から順に意味が決まっている
*=任意の値、,=複数指定、-=範囲、/=ステップ- 日と曜日を両方指定するとAND ではなく OR で評価される(標準cronの仕様)
- GitHub Actions等のクラウドスケジューラはUTC基準で評価される
- Quartz/SpringなどはUnixのcrontabと異なる6フィールド(秒付き)形式を使う
1. 5フィールドの意味 / What each field means
cron式は左から「分」「時」「日」「月」「曜日」の順で固定されています。フィールドの順番を 間違えると意図しない時刻で実行されてしまうため、まずこの並びを覚えるのが最短ルートです。
| 位置 | フィールド | 取りうる値 | 備考 |
|---|---|---|---|
| 1 | 分 (minute) | 0-59 | - |
| 2 | 時 (hour) | 0-23 | 24時間表記 |
| 3 | 日 (day of month) | 1-31 | 月末日は月により変動 |
| 4 | 月 (month) | 1-12 | JAN-DEC等の略称対応系もある |
| 5 | 曜日 (day of week) | 0-6 (0=日曜) or 7=日曜 | 実装により0/7両方が日曜を指すことがある |
0 3 * * *
│ │ │ │ │
│ │ │ │ └─ 曜日(何曜日でもよい)
│ │ │ └─── 月(何月でもよい)
│ │ └───── 日(何日でもよい)
│ └─────── 時 = 3時
└───────── 分 = 0分
→ 毎日 3:00 に実行2. 特殊文字の使い方 / Special characters
| 記号 | 意味 | 例 |
|---|---|---|
* | そのフィールドの全ての値(任意) | * * * * * = 毎分 |
, | 複数の値をリスト指定 | 0 9,18 * * * = 9時と18時 |
- | 範囲を指定 | 0 9-17 * * * = 9〜17時の毎時0分 |
/ | ステップ(間隔)を指定 | */15 * * * * = 15分ごと |
- + / | 範囲内をステップで指定 | 0 9-17/2 * * * = 9,11,13,15,17時 |
* means "every value," , lists specific values, -defines an inclusive range, and / applies a step. They can be combined, e.g.10-30/5 means 10, 15, 20, 25, 30 within that field.
3. よく使うパターン早見表 / Common pattern lookup table
| cron式 | 意味 |
|---|---|
* * * * * | 毎分 |
*/5 * * * * | 5分ごと |
0 * * * * | 毎時0分 |
0 3 * * * | 毎日3:00 |
0 9 * * 1-5 | 平日(月〜金)9:00 |
0 0 * * 0 | 毎週日曜0:00 |
0 0 1 * * | 毎月1日0:00 |
0 0 1 1 * | 毎年1月1日0:00 |
0 0 L * * | 月末0:00(L対応の実装のみ) |
4. 日フィールドと曜日フィールドの罠 / The day-of-month vs. day-of-week trap
標準cronの仕様で最もハマりやすいのがここです。日(第3フィールド)と曜日(第5フィールド)の 両方を * 以外で指定すると、AND ではなく OR で評価されます。
0 0 15 * 1
→ 「毎月15日」 OR 「毎週月曜日」の 0:00 に実行される
(「15日かつ月曜日」ではない)「第3金曜日だけ実行したい」のような AND 条件が必要な場合、標準cronの構文だけでは表現できません。 ジョブ側で曜日と日付を追加チェックするか、L/# などの拡張構文(Quartzなど 一部実装のみ対応)を使う必要があります。
5. タイムゾーンの注意点 / Timezone caveats
Linux/macOSの crontab は原則としてシステムのローカルタイムゾーンで 評価されます(一部のcron実装は crontab 内で TZ= 変数を指定可能)。一方、GitHub Actionsのcronトリガーは常にUTC基準で評価されるため、日本時間で 「毎朝9時」を実行したい場合は 0 0 * * *(UTC 0時 = JST 9時)のようにオフセットを 手動で計算する必要があります。
System crontab typically evaluates in local time, but hosted schedulers like GitHub Actions always use UTC — a frequent source of "my job ran 9 hours off" bugs.
6. 6フィールド(秒付き)cron式との違い / 6-field cron (with seconds)
標準crontabは5フィールドですが、Java の Quartz Scheduler や Spring の @Scheduledは先頭に秒フィールドを追加した6フィールド形式を使います。
| 形式 | フィールド構成 | 代表的な利用箇所 |
|---|---|---|
| 標準(5フィールド) | 分 時 日 月 曜日 | crontab, GitHub Actions, node-cron(デフォルト) |
| Quartz(6〜7フィールド) | 秒 分 時 日 月 曜日 [年] | Java Quartz, Spring @Scheduled(cron=...) |
同じ見た目のcron式でも、パーサーが5フィールド前提か6フィールド前提かでフィールドのズレが起き、 意図しない時刻で実行される事故につながります。ライブラリのドキュメントで前提フィールド数を 必ず確認してください。
まとめ / Summary
cron式は「分 時 日 月 曜日」の5フィールドと * , - / の4種類の記号だけで あらゆる定期実行を表現できます。落とし穴は日と曜日のOR評価、タイムゾーンの前提、 5/6フィールドの混同の3点です。書いたcron式が意図通りか不安な場合は、実行前にパーサーで 次回実行時刻を確認する習慣をつけましょう。
A cron expression is five fields (minute, hour, day-of-month, month, day-of-week) combined with four operators. The three classic traps are: day-of-month and day-of-week are OR'd together (not AND'd), hosted schedulers often run in UTC regardless of your local timezone, and Quartz-style 6-field cron (with seconds) is not interchangeable with standard 5-field crontab syntax. Always verify the next run times before deploying a new schedule.
関連ツール / Related tools
- Cron Parser — cron式の解読・次回実行予定表示
- Timestamp Converter — 実行時刻の確認に