本文へスキップ
totonoe
システム入力

cronの「0 9 * * 1」が読めるようになる──5つの数字と、月末指定の罠

cronの実行時刻指定は5つのフィールドの意味さえ分かれば読めます。0 9 * * 1が毎週月曜9時になる理由、日と曜日の両方指定はORになる罠、31日指定が動かない月末の落とし穴を整理します。

サーバーの設定ファイルや自動化ツールの画面で見かける 0 9 * * 1 のような呪文。意味を知らないまま「とりあえずコピペ」で使ってしまい、想定と違う時刻に動いてしまった経験がある方もいるのではないでしょうか。

結論を先に書きます。

cronの書式は「分・時・日・月・曜日」という5つの数字(またはアスタリスク)が並んでいるだけで、この順番さえ覚えれば大半の式は読めます。0 9 * * 1 なら「分=0、時=9、日=(毎日)、月=(毎月)、曜日=1(月曜)」——つまり毎週月曜の9時0分という意味になります。


5つのフィールドの並び順

cronの式は、左から右へ次の順番で並びます。

分 時 日 月 曜日
*  *  *  *  *
0-59 0-23 1-31 1-12 0-7(0と7=日曜)

各フィールドに数字を入れると「その値のときだけ実行」、*(アスタリスク)を入れると「無条件(毎回)」を意味します。

曜日意味
0 9 * * *09***毎朝9時0分
*/15 * * * *15刻み****15分おき
0 0 1 * *001**毎月1日の0時0分
0 9 * * 109**1毎週月曜9時0分
30 18 * * 1-53018**1〜5平日18時30分

曜日フィールドは0が日曜、1が月曜、以降6が土曜まで進み、7も日曜として扱われます(0と7は同じ意味の別表記)。慣れないうちは、この5フィールドの表を手元に置いておくだけで、ほとんどの式は機械的に読み解けます。

数字1つだけでなく、範囲・刻み・列挙も書ける

各フィールドには単一の数字だけでなく、次のような書き方も使えます。

記法意味
,(カンマ)複数の値を列挙0 9,18 * * * → 毎日9時と18時
-(ハイフン)範囲を指定* 9-17 * * * → 9時台〜17時台の毎分
/(スラッシュ)一定間隔で刻む*/15 * * * * → 15分おき
MON-FRI曜日は英語名の範囲も可0 9 * * MON-FRI → 平日9時

これらは組み合わせて使うこともでき、9-17/2 なら「9時から17時の範囲で2時間おき」という意味になります。数字の並びに見えて、実は範囲演算子付きの短い式が書けるようになっている、という点を知っておくと、複雑な式を見たときにも慌てず分解できます。

「日」と「曜日」を両方指定したときの罠

もう一つ、cronで意外に知られていない挙動があります。それは**「日」と「曜日」を両方とも * 以外で指定したときの解釈**です。

普通、複数のフィールドを指定すると「すべての条件を満たしたとき」(AND)に実行されると思いがちですが、**日と曜日の組み合わせだけは例外で、どちらか一方に合えば実行される(OR)**という挙動をします。

例えば 0 9 1 * 1 は「毎月1日」と「毎週月曜」の両方が9時に実行対象になり、「1日かつ月曜」の日だけ実行されるわけではありません。この仕様はUNIX系のcronで古くから定着しているもので、直感に反するため設定ミスの原因になりやすいポイントです。

「31日」指定がある月にしか動かない

もう一つの落とし穴が、日にちの指定範囲は1〜31までしかなく、実在しない日付のチェックはしてくれないという点です。

例えば「毎月末に集計処理を回したい」と考えて 0 0 31 * * と設定してしまうと、31日が存在しない月(2月・4月・6月・9月・11月)ではその月は一切実行されません。「毎月末」を狙うなら31日固定ではなく、月初1日に前月分をまとめて処理する、あるいは月末日を動的に計算するスクリプト側の工夫が必要になります。31という数字が並んでいるcron式を見かけたら、その月に本当に31日があるかを一度疑ってみるとよい習慣です。

自分が書いた(あるいはコピペした)cron式が実際にはどんな意味なのか、次にいつ実行されるのかを日本語で確認したいときは、cron式を整える に貼り付けるとその場で翻訳されます。逆に「毎週月曜の朝9時」のような日本語からcron式を組み立てたいときにも使えるので、月末の罠を含めて設定前の確認に役立ちます。

KOINOBORI ECOSYSTEM

私たちが運営するサイト