Cron 式 パーサー & ビルダー

5 フィールドの cron 式を検証して次回 N 回の実行時刻をプレビュー、または頻度ピッカー(分/時/日/週/月/年)から式を組み立て。

Loading…

すべての処理はブラウザ内で実行されます — ファイルや入力はサーバへ送信されません。

5 つのフィールドと有効範囲

古典的な cron 式は空白区切りの 5 フィールドです。順序は 分・時・日・ 月・曜日で、左から右に向かって細かい粒度から粗い粒度へ並び、最後の 曜日だけが月の右側に置かれます。各フィールドは範囲・リスト・ アスタリスクを受け付けます。下表は有効範囲です。

#フィールド範囲名前形
10–59
20–23
3日 (DOM)1–31
41–12JAN–DEC
5曜日 (DOW)0–6SUN–SAT

古典 cron で使える演算子

演算子意味
*そのフィールドの全有効値。* * * * * → every minute
,値のリスト。0 9,12,18 * * * → 09:00, 12:00, 18:00 daily
-両端を含む範囲。0 9 * * 1-5 → 09:00 Mon–Fri
/ステップ。*/n は n ごと。a-b/n は範囲 a-b 内で n ごと。*/15 * * * * → :00, :15, :30, :45 every hour
name月や曜日の 3 文字エイリアス (大文字小文字を区別しない)。0 0 * JAN MON → midnight every Monday in January

実務で頻出するパターン

実運用で書く cron ジョブの大半は、いくつかの形に収まります。下記 のどれかをコピーして調整するのが速いです。

*/5 * * * *5 分ごと。
0 * * * *毎時 0 分。
0 3 * * *毎日 03:00 — バックアップの定番枠。
0 9 * * MON毎週月曜 09:00 — 朝会のリマインダー。
0 18 * * 1-5平日 18:00 — 業務終了時のクリーンアップ。
0 0 1 * *毎月 1 日 00:00 — 請求バッチ。
15 2 * * 0毎週日曜 02:15 — トラフィックが少ない時間帯の重バッチ。
0 0 1 1 *1 月 1 日 00:00 — 年次リセット。
*/10 9-17 * * 1-5平日の 9〜17 時に 10 分ごと。

cron の方言: どこで規則が分かれるか

「cron」は単一の仕様ではありません。POSIX が上述の 5 フィールド 構文を定めています。Vixie cron (BSD 由来で Linux の事実上の標準 になった実装) は曜日名、@reboot / @daily / @hourly のショート カット、そして DOM と DOW を両方制限したときの「暗黙の OR」を 追加しています。この発散はだれもが初めて遭遇したときに驚きます。 Quartz (Spring・Hangfire・Quartz.NET が採用する Java スケジューラ) は秒フィールドを先頭に、任意の年フィールドを末尾に追加し、 ? L W # を「未指定」「月末」「最寄りの平日」「第 n 曜日」として 加えます。0 15 10 ? * MON-FRI は Quartz では有効ですが POSIX では 不正です。

systemd タイマーは cron 式を捨て、独自の OnCalendar 構文 (例: Mon..Fri 18:00) を採用しています。AWS EventBridge は Quartz に 近い 6 フィールド形式 (秒は無く年あり) を使います。Cloudflare Workers の cron トリガーは古典的な 5 フィールド POSIX 方言を UTC で解釈します。異なるシステム間で式をコピペする際は、両側が どの方言を話すかを必ず確認してください。上のツールは POSIX 5 フィールドを採用し、DOM と DOW は AND で扱います。

落とし穴 3 つ

1 つ目、タイムゾーンです。crond をはじめ多くのスケジューラは cron 式をサーバーのローカルタイムで解釈するため、夏時間の切り替えで 年 2 回静かに壊れ、データセンター間で実行スケジュールが揃わなく なります。クラウド系スケジューラ (Cloudflare Workers・GitHub Actions・AWS EventBridge) は UTC を既定とします。どちらのゾーン を採るかを最初に決めてから式を書き、システムが自分と同じ前提で 動くと思い込まないでください。

2 つ目、DOM と DOW の罠です。Vixie cron では 0 0 1 * MON は 毎月 1 日の 00:00 と 毎週月曜の 00:00 の和集合で動き、想定の 約 6 倍の頻度になります。POSIX と本ツールでは両条件を同時に 満たす場合のみ実行されます (1 日にかかる月曜だけ、年 1 回程度)。 「どちらか一方でも」が必要なら、曖昧な 1 行ではなく 2 行に分けて ください。

3 つ目、「5 分ごと」は */5 が常に意味するものではありません。 時フィールドの */5 は 0 時から 5 ずつ進み、0・5・10・15・20 と なり、4・9・14・19 にはなりません。オフセットが必要なら明示的な リストを使うか、範囲をずらして 4-23/5 と書きます。スラッシュは 常に範囲の下端を起点とし、現在時刻からではありません。

使い方

**Parser** タブに 5 フィールドの cron 式を貼り付けると、各フィールド — 分(0–59)、時(0–23)、日(1–31)、月(1–12 または `JAN-DEC`)、曜日(0–6 または `SUN-SAT`、日曜が 0) — を検証し、次回 N 回の発火時刻を表示します。対応構文: `*`(任意)、範囲 `a-b`、リスト `a,b,c`、ステップ `*/n` と `a-b/n`、大文字小文字を区別しない月・曜日名。日と曜日の両方を制限した場合、本パーサーは Vixie cron の OR ではなく **AND**(POSIX 動作)を採用します — トレードオフは FAQ を参照してください。

**Builder** タブでは頻度ピッカーから式を組み立てられます。*毎分・毎時・毎日・毎週・毎月・毎年* を選んで条件を絞ります。例えば「15 分ごと、平日のみ、9:00–17:00」は `*/15 9-17 * * 1-5` を生成します。次回実行プレビューはホストブラウザのローカルタイムゾーンを使うので、同じタイムゾーンのサーバー上の `/etc/crontab` の挙動と一致します。本番 cron が UTC で動く場合は、デプロイ前にオフセットを心で加減してください。パーサーは自己完結 — ネットワーク要求や外部 cron ライブラリ無し — なので、式とマシンの時計はページ外に出ません。

毎時 00 分のメンテナンスフック

入力
expression:  0 * * * *
starting:    Mon 2026-05-18 14:00 local time
preview:     next 5 runs
出力
Mon 2026-05-18 15:00
Mon 2026-05-18 16:00
Mon 2026-05-18 17:00
Mon 2026-05-18 18:00
Mon 2026-05-18 19:00

`0 * * * *` は「毎時 00 分」の標準表現 — 分は 0 で固定、他のフィールドはすべて `*`。よくある間違いは「毎時」のつもりで `* * * * *` と書くことで、実際には毎分発火します(60 倍の頻度)。本当に毎時にしたいなら分フィールドを固定します。1 時間より細かい頻度には `*/15` か `0,15,30,45` を使います。00 分起点なら 2 つは同等ですが、Vixie cron では `0,15,30,45` の方が HUP/再起動のタイミングを跨いで正しく残ります。`*/15` は crontab 解析時に一度だけ読まれます。

平日営業時間内のポーリング

入力
expression:  */15 9-17 * * 1-5
interpret:   every 15 minutes, 09:00–17:45, Monday–Friday
preview:     next 4 runs after Fri 2026-05-15 17:45
出力
Mon 2026-05-18 09:00
Mon 2026-05-18 09:15
Mon 2026-05-18 09:30
Mon 2026-05-18 09:45

# Note: 17:00–17:45 inclusive on Friday, then the cron sleeps the entire
# weekend and resumes Monday 09:00. The 4× /hour cadence × 9 active hours
# × 5 weekdays = 180 fires per week.

営業時間内のヘルスチェックの典型例。時間範囲 `9-17` は *両端を含む* ので 17:45 も発火します。曜日 `1-5` は月曜から金曜(日曜=0、土曜=6)。`*/15 9-17` の組み合わせは 1 時間に 4 回 × 9 時間 = 平日 1 日 36 回、週 180 回です。夜間アイドル前に 18:00 ちょうどで最後の発火が必要なら、OR として追加します: `0,15,30,45 9-17 * * 1-5` に切り替え、`0 18 * * 1-5` を別行で追加。1 つの式で異なる時パターンを OR することはできません。

月末レポート — 日 と 曜日 の落とし穴

入力
expression:  0 9 28-31 * 1
interpret:   POSIX (AND) — only when the 28th-31st is also a Monday
             Vixie (OR) — every day 28-31 OR every Monday
出力
POSIX behavior (this parser):
  Mon 2026-12-28 09:00     # 28th is a Monday
  Mon 2027-03-29 09:00     # next 28-31 + Monday match
  ...

Vixie crond behavior (most Linux distros):
  Every day 28-31 of any month
  PLUS every Monday
  ≈ 4 + 4 = 8 fires per month on average

最も引用される cron の落とし穴です。POSIX § は日と曜日の両方が制限されると AND(積集合)になると規定しますが、ほとんどの Linux ディストリビューションに付く Vixie cron(`cronie` / `cron`)は OR(和集合)します。同じ式が、ローカルテストと本番サーバで 5 倍頻度で発火することになります。両方を制限する式はこのパーサーで一度チェックしてください。本当に月末ランが欲しいなら、`0 9 28-31 * *` のように曜日を `*` のままにし、ジョブ本体に日付チェックを入れます: `[ "$(date -d tomorrow +%d)" = "01" ] && run.sh` は *本当の最終日* だけ発火します。

よくある質問

ここでは 5 フィールドですが、6 や 7 フィールドの式を見ることもあるのはなぜですか?

標準 Unix cron — Linux・BSD・macOS の `/etc/crontab` が解析するもの — は 5 フィールド: 分、時、日、月、曜日 を使います。6 フィールド版は先頭に **秒** フィールドを追加したもので、Quartz Scheduler(Java)や多くの AWS / Spring スケジューラが受け付けます。7 フィールド版は末尾に **年** フィールドを追加したもので Quartz 固有です。先頭秒の形式は `WithSeconds` オプション付きの robfig/cron など一部の Go ライブラリも採用します。6 フィールドの式をここに貼ると「フィールド過多」エラーになります — 秒(または年)を落として、分以降の中央 5 つだけを解析してください。標準の `crond` はどの方言でも 1 分に 1 回より速く発火することはできません。

cron は `@daily`, `@reboot` といったショートカットに対応していますか?

Vixie cron は 7 つのニックネームに対応します: `@yearly` / `@annually`(= `0 0 1 1 *`)、`@monthly`(= `0 0 1 * *`)、`@weekly`(= `0 0 * * 0`)、`@daily` / `@midnight`(= `0 0 * * *`)、`@hourly`(= `0 * * * *`)、`@reboot`(システム起動時に 1 回)。ニックネームは Vixie 拡張で POSIX には無いため、一部の Docker ベースイメージで使われる最小限の busybox-cron では動作しないことがあります。本パーサーはニックネームを受け付け **ません** — 展開した 5 フィールド形式で貼り付けてください。`@reboot` には等価な式が無く、時間トリガーではなくイベントトリガー(起動)です。同等の「起動時 1 回」セマンティクスには `OnBootSec` を使う systemd timer が現代の代替です。

このパーサーはどのタイムゾーンを使いますか?本番 cron は UTC 動作です。

次回実行プレビューはブラウザのローカルタイムゾーン(`Intl.DateTimeFormat().resolvedOptions().timeZone` から取得)を使います。サーバが UTC で動作しブラウザが JST や KST だと、プレビューは実際のサーバ発火より 9 時間後を示します。多くの現代 cron は環境変数 `CRON_TZ=...` または `TZ=...` を尊重します — `/etc/crontab` で行ごと、または全体で設定できます。systemd timer では `OnCalendar=` ディレクティブが `OnCalendar=Mon..Fri 09:00 Asia/Tokyo` のように明示的なゾーンを受け付けます。サマータイムが問題を悪化させます: DST を採用する地域でローカル 02:30 にスケジュールしたジョブは、春の進行日にはスキップ、秋の戻り日には 2 回発火します(素朴な cron の場合)。本番ジョブを UTC で動かすことが標準的な推奨である理由です。

`*/5` は `0/5` や `0,5,10,15,...` とどう違いますか?

分フィールドでは、3 つの形式は POSIX/Vixie cron で同等です: 0、5、10、15、20、25、30、35、40、45、50、55 分に発火します。差は開始点が 0 でない場合や非標準範囲で現れます。`5/15`(Quartz)は「5 から始めて 15 ごと」→ 5、20、35、50 で、`*/15` はこれを *生成しません*。`1-30/5` は「1–30 の間で 5 分ごと」→ 1、6、11、16、21、26。POSIX/Vixie cron は `a-b/n` 形式に対応しますが `a/n`(開始+ステップ)には対応しません — それは Quartz 拡張です。迷ったら明示的リスト `0,5,10,...` に展開すれば最大限の移植性が得られます。分をスキップしたいときもリスト形式が役立ちます — `0,3,6,9` は不規則間隔で 1 時間に 4 回発火します。

なぜ Linux の cron はパーサーの予測と違う日に発火しますか?

ほぼ確実に例 3 で説明した DOM/DOW の不一致です。本パーサーは POSIX §(AND)に従いますが、ほとんどの Linux ディストリビューションに付く cron デーモンは Vixie 慣例(OR)に従います。サーバで確認するには `man 5 crontab` を実行し「day-of-week」を検索 — マンページにローカル動作が明示されています。他の可能な原因: 編集環境とサーバのタイムゾーンの不一致(上の UTC FAQ 参照)、`cron` が動いていない(`systemctl status cron`)、メール未設定で `MAILTO=` が静かに失敗、ユーザの `PATH` に `/usr/local/bin` が無くスクリプトのシェバンは解決するが最初のコマンドが失敗、など。式のセマンティクスをデバッグする前にまず `* * * * * date >> /tmp/cron.log` をテストの crontab に追加して cron が発火していること自体を確認してください。

cron 対 systemd timer 対 Kubernetes CronJob はどう使い分けますか?

**cron** は単一 Linux ホストで `/etc/crontab` と稼働時間を管理し、シェルスクリプト的な自動化(ログローテーション、バックアップ、簡易ポーリング、趣味プロジェクト)を行う場合に最適です。**systemd timer** は既にサービスを systemd で管理しており、`journalctl` で統一されたログ、依存順序(`network-online.target` の *後*)、サンダリングハード回避のランダム遅延、再起動を跨いだ未実行ジョブの永続化(`Persistent=true`)が欲しい場合に使います。**Kubernetes CronJob** はワークロードがクラスタで動く場合に — Pod 単位のリソース分離、自動再起動・リトライ、通常の k8s ツーリングによる可観測性が得られますが、小さなジョブでも 10〜30 秒のコールドスタート遅延が代償です。クラスタ無しのクラウドネイティブな単発処理には、**AWS EventBridge Scheduler**、**Cloud Scheduler**、**Azure Logic Apps** がすべて cron 形式の式を受け付け、ジョブがアイドルの間は計算を走らせずに済みます。

関連する概念

cron は AT&T ベル研究所で第 7 版 Unix(1979 年)の一部として誕生し、Brian Kernighan が書いたとされます。オリジナルは `/usr/lib/crontab` を 1 分に 1 回スキャンして一致するエントリを exec するデーモンでした。**Paul Vixie のリライト**(1987 年)はユーザ別 crontab、月・曜日の名前付きエイリアス、`@daily` / `@reboot` ニックネーム、そして翌年公開された POSIX 標準から逸脱した **DOM + DOW の OR セマンティクス** を導入しました。Vixie cron は Linux と BSD の事実上の標準となり、現代の派生として `cronie`(Red Hat / Fedora)、`bcron`(Debian)、`dcron`(Alpine、Slackware)があります。POSIX 厳格実装は主に商用 Unix と組み込み busybox-cron に存在します。DOM/DOW の不一致は最も引用される cron の落とし穴であり、POSIX 自身より 7 年ほど先行します。

**形式そのものにも方言** がフィールド数を超えて存在します。`JAN-DEC` と `SUN-SAT` エイリアスは Vixie 拡張で POSIX には無く、Quartz Scheduler は秒フィールド、年フィールド、特殊文字 `L`(最後)、`W`(平日)、`#`(月の N 番目曜日)、`?`(DOM/DOW で値指定なし)を追加します。AWS EventBridge は Quartz セマンティクスに従いつつ `?` 要件を追加します。Spring の `@Scheduled` はさらに別の変形です。cron 式をシステム間でコピーするときはフィールド数、DOM/DOW セマンティクス、名前付きエイリアスが対応されるかを確認してください — あるシステムで動く式が別のシステムでは静かに誤動作したり解析を拒否したりすることがあります。

3 つの **現代的代替** が異なる領域で cron の地位を奪っています。**systemd timer** は systemd 管理の Linux サーバ(2015 年以降ほとんどのディストリビューション)で cron を置き換えます — unit システムと統合し、journald にログ、ランダム化と永続化に対応し、より読みやすい `OnCalendar=Mon..Fri 09:00` 構文を受け付けます。**Kubernetes CronJob** はコンテナ化されたワークロードに Pod 分離と再試行ポリシー付きで cron セマンティクスをもたらします。**クラウドマネージドスケジューラ**(AWS EventBridge Scheduler、Google Cloud Scheduler、Azure Logic Apps Scheduler)は cron 式を受け付けつつマネージドインフラで動作し、常時稼働ホストを不要にします。アプリケーション内のタスクスケジューリングには、Java の Quartz、Python の APScheduler、Go の robfig/cron、Node の node-cron といったライブラリが cron セマンティクスを直接埋め込みます。これらの代替が存在しても、素のままの crontab はあらゆる Unix 系マシンで生き続けます — その小さな表面積と `/etc/crontab` のシンプルさが、ほとんどの置換候補より長生きさせるでしょう。

関連記事

関連ツール