Cron 式パーサー

スペース区切りの5つのフィールド、または @daily のような短縮形を入力します。

引き継いだ crontab に 0 */2 * * 1-5 や 30 3 * JAN,JUL 1 のような行が並んでいることがあります。このパーサーは各フィールドを、実際に一致する値の集合へ展開します。*/2 がどこまでを対象にするのかを推測しなくても、時フィールドで選ばれる12通りの値と、その件数がそのまま表示されます。さらに、正規化された5フィールド形式、よく知られた落とし穴に当てはまるときの警告、お使いのタイムゾーンで計算した次の5回分の実行日時も確認できます。

Cron 式を解析する手順

  1. 1

    式を貼り付ける

    5つのフィールドからなる行(`* * * * *`)です。順に分、時、日、月、曜日を表します。`@daily` のような短縮形も使えます。

  2. 2

    展開されたフィールドを読む

    各フィールドについて、一致する値とその件数が一覧で表示されます。時フィールドの `*/2` なら、0、2、4 と、残り9つの値がそのまま並びます。

  3. 3

    次回以降の実行日時を確認する

    今後5回分の実行日時が、お使いのブラウザで、端末に設定されたタイムゾーンをもとに計算されます。意図と合わなければ式を調整してください。

  4. 4

    警告を読む

    パーサーは落とし穴を指摘します。日と曜日の両方が指定されている場合、カレンダー上に存在しない日付を指している場合、標準の cron が解釈できない演算子が含まれている場合です。

各フィールドが展開される内容

フィールドは1つの値ではなく、値の集合です。その集合がどれくらい大きいかが分かれば、たいていの疑問はそれだけで解決します。

フィールド 範囲 * の一致数 補足
分 0-59 60通り ジョブが暴走する原因として最も多いフィールド
時 0-23 24通り 24時間表記です。1-12ではありません
日 1-31 31通り 日数の少ない月では、存在しない日はそのまま飛ばされます
月 1-12 12通り JAN から DEC の表記も使えます
曜日 0-7 7通り 0 も 7 も日曜日です

フィールド内で使える演算子は次のとおりです。* はすべての値、1,5,10 はリスト、1-5 は範囲、*/15 は範囲の先頭から数えるステップ、0-45/15 は範囲内のステップです。

名前と短縮形も使えます

月と曜日は名前でも指定でき、一致する数値へ展開されます。たとえば 30 3 * JAN,JUL 1 なら、月は 1, 7、曜日は 1 と表示されます。名前付きの短縮形は、ほかの処理より先に5フィールド形式へ展開されます。

短縮形 展開後 意味
@yearly、@annually 0 0 1 1 * 1月1日の0時
@monthly 0 0 1 * * 毎月1日の0時
@weekly 0 0 * * 0 毎週日曜日の0時
@daily、@midnight 0 0 * * * 毎日0時
@hourly 0 * * * * 毎時0分

@reboot も認識されますが、展開できるスケジュールはありません。マシンの起動時に1回だけ実行されるため、プレビューする実行日時が存在しないからです。

目を通しておきたい警告

  • 日と曜日の両方を指定した場合。 0 0 1 * MON は「1日、ただし月曜日のときだけ」という意味ではありません。標準の cron は、2つの日付フィールドが両方とも指定されているとき、これを OR として扱います。つまりこの行は、毎月1日と毎週月曜日のどちらにも実行されます。パーサーはこの警告を表示し、実行日時のプレビューも OR のルールに従います。
  • 存在しない日付を指定した場合。 0 0 30 2 * は2月30日を指しています。構文としては正しく、cron も受け付けますが、実行されることは一度もありません。パーサーは、説明のない空のリストを見せる代わりに、その事実をはっきり伝えます。
  • Quartz の演算子。 L(最終)、W(最も近い平日)、#(その月のN番目の該当曜日)、? は Quartz の拡張であり、標準の crontab にはありません。5フィールドの行に含まれていても認識はされますが、警告が表示され、そのフィールドには値の一覧ではなく Quartz の演算子である旨が示されます。標準の cron ではその行自体が実行されないため、実行日時は計算しません。

そのまま拒否されるもの

  • フィールド数が違う式。 秒を含む6フィールドの Quartz の行や、年を含む7フィールドの行は、フィールド数の時点で拒否されます。
  • 範囲外の値。 たとえば分の75や月の13です。
  • 逆向きの範囲。 5-1 のような指定です。
  • 0のステップ。 */0 のような指定です。

エラーには原因となったフィールドと値が必ず示されるので、行全体を書き直さずに1か所だけ直せます。

タイムゾーン

次回以降の実行日時は、お使いのブラウザで、端末に設定されたタイムゾーンをもとに計算されます。一方 crontab は、それが動いているマシンのタイムゾーンで実行されます。サーバーが UTC で動いていて手元の端末が日本時間(JST、UTC+9)なら、0 0 * * * が実際に動くのは日本時間の9時です。見比べる前に、その差を時刻に足し引きしてください。

よくある質問

スケジュールとしては扱えません。秒を含む6フィールドの Quartz の行や、年を含む7フィールドの行は、フィールド数の時点で拒否されます。通常の5フィールドの行に Quartz の演算子(L、W、#、?)が含まれている場合は別で、認識したうえで警告を表示します。ただし標準の cron でもその行は実行されないため、実行日時は計算しません。

よくある原因は2つです。1つは、お使いの端末と crontab が動くサーバーとのタイムゾーンの差。もう1つは、日と曜日の両方を指定していることです。この2つが同時に指定されている場合、cron は両方が一致したときではなく、どちらか一方でも一致したときにジョブを実行します。そのため 0 0 1 * MON は、多くの人が思っているよりずっと頻繁に実行されます。各フィールドの横に表示される件数を見れば、思っていたより広い範囲を指しているフィールドをすぐに見つけられます。

はい。Kubernetes は標準の5フィールド構文を使います。注意が必要なのは時計だけです。CronJob はクラスターのタイムゾーン(spec.timeZone で指定しないかぎり UTC)で実行されますが、ここでのプレビューはお使いの端末のタイムゾーンを使います。日本時間で運用していれば、その差は9時間です。

どちらも、Linux の cron が5つのフィールドの代わりに受け付ける名前付きの短縮形です。@daily(@midnight も同じ)は 0 0 * * *、@weekly は 0 0 * * 0、@monthly は 0 0 1 * *、@yearly(@annually も同じ)は 0 0 1 1 *、@hourly は 0 * * * * です。どれを貼り付けても、展開後の5フィールド形式が表示されます。@reboot だけは例外で、起動時に実行されるためスケジュールがなく、実行日時も表示されません。

関連ツール

このツールは他の言語でも利用できます