cron式の読み方と次に動く日時
区切りは - でも / でも読みます。時刻は省けます。
毎月1日、または毎週月曜日の0時0分に動きます。
日と曜日は「どちらか」です: 日の欄と曜日の欄の両方が指定されています。この場合、cron は「両方に当たる日」ではなく「どちらかに当たる日」に動きます。日を狭めるつもりで曜日を足すと、かえって動く日が増えます。
- いつの時刻に
- 0時0分
- どの日に
- 毎月1日、または毎週月曜日日の欄と曜日の欄のどちらかに当たれば動きます
- どの決まりで読んだか
- POSIX の5フィールド分・時・日・月・曜日。曜日は 0〜6 で 0 が日曜。Quartz や AWS の書き方とは別です
| 欄 | 書いたもの | 当たる値 |
|---|---|---|
| 分0〜59 | 0 | 0分 |
| 時0〜23 | 0 | 0時 |
| 日1〜31 | 1 | 1日 |
| 月1〜12 | * | 毎月1月から12月まで12個 |
| 曜日0〜6 | 1 | 月曜日 |
この式は POSIX の crontab の書き方だけでできています。
その月のどの日に動くか
日の欄で当たったのか、曜日の欄で当たったのかを、色ではなく文字でも出しています。
次に動く日時
| 回 | 日時 | 基準から |
|---|---|---|
| 1 | 2026年10月1日(木)0時00分 | 2日後 |
| 2 | 2026年10月5日(月)0時00分 | 6日後 |
| 3 | 2026年10月12日(月)0時00分 | 13日後 |
| 4 | 2026年10月19日(月)0時00分 | 20日後 |
| 5 | 2026年10月26日(月)0時00分 | 27日後 |
| 6 | 2026年11月1日(日)0時00分 | 33日後 |
| 7 | 2026年11月2日(月)0時00分 | 34日後 |
| 8 | 2026年11月9日(月)0時00分 | 41日後 |
この日時は「この端末の時間帯」の壁時計として読んでいます。cron は動かしている機械の時間帯で動くので、 手元とサーバーの時間帯が違えば、同じ式でも違う時刻に動きます(日本と UTC なら9時間ずれ、日付も1日ずれることがあります)。 入れた数字を、そのまま壁時計の数字として扱っています。
やってみる
1問目 / 全5問
よくある質問
0 0 1 * 1 はいつ動きますか?「1日が月曜日のとき」ですか?
違います。毎月1日と、毎週月曜日の、どちらかに当たる日すべてに動きます。POSIXのcrontabは「日の欄と曜日の欄が両方とも指定されているときは、月と日に当たる日か、曜日に当たる日のどちらかに当たれば実行する」と定めています。同じ規格の例にも「0 0 1,15 * 1 は毎月1日と15日、および毎週月曜に動く」と書かれています。日を絞るつもりで曜日を足すと、動く日はかえって増えます。
日と曜日を「両方に当たる日」にしたいときはどう書きますか?
cronの式だけでは書けません。第1月曜だけに動かしたいときは、日の欄を1-7にして曜日の欄は「*」のままにし、実行するコマンドの側で「今日は月曜か」を確かめる、という書き方がよく使われます。0 0 1-7 * * なら毎月1日から7日までに動くので、そのうち月曜の1回だけをコマンド側で選ぶことになります。ここで曜日の欄にも月曜と書いてしまうと、日と曜日が両方とも指定された式になって「どちらかに当たれば動く」に変わり、毎週月曜にも動いてしまいます。QuartzやSpringのcron式には「その月の第n曜日」を表す # があり、0 0 0 ? * MON#1 のように書けますが、これはPOSIXのcronでは使えません。
0 0 30 2 * は次にいつ動きますか?
永遠に動きません。2月30日はどの年にも存在しないからです。cronは近い日に寄せることをしないので、エラーも出さずにただ動きません。この画面は9年ぶん探しても見つからなければ「永遠に来ません」と理由つきで出します。
*/15 はPOSIXの書き方ですか?
違います。POSIXのcrontabが定めているのは、アスタリスク・数・範囲(1-5)・その並び(1,3,5)の4つだけで、「何おきか」を表すスラッシュはありません。これはVixie cronが足したもので、いまはLinuxのcron(cronie)・Quartz・Spring・AWS EventBridgeが持っています。POSIXの書き方だけで同じことを書くなら 0,15,30,45 と並べます。この画面は読みますが、拡張であることを画面に出します。
cronはどのタイムゾーンで動きますか?
動かしている機械に設定された時間帯です。日本の手元で「0 9 * * *」と書いても、サーバーの時間帯がUTCなら日本時間の18時に動きます。Linuxのcron(cronie)にはCRON_TZという指定があり、その表だけ別の時間帯で読ませることもできます。さらに夏時間のある地域では、切り替えの日に存在しない時刻と二度来る時刻ができて、その時刻を指した仕事は飛ばされたり2回動いたりします。
欄が6つある式を貼ったら読めませんと出ました
6つの欄を持つのは別の方言です。QuartzとSpringは先頭に「秒」が付いて6〜7個、AWS EventBridgeは末尾に「年」が付いて6個です。同じ6個でも増えている場所が逆なので、そのまま5個として読むと答えが全部ずれます。この画面はPOSIXの5つ(分・時・日・月・曜日)でだけ計算するので、黙って読み替えずに理由を出して止まります。
cron式を日本語に直して、次に動く日時を出します。日の欄と曜日の欄は「どちらかに当たる日」です。ここでいちばん多くの人がつまずきます。
日と曜日は「かつ」ではなく「または」です
0 0 1 * 1 は、1日が月曜日のときという意味ではありません。毎月1日と毎週月曜日のどちらかに当たる日ぜんぶに動きます。 2026年9月なら、1日(火)と7・14・21・28日(月)の5日です。 「1日が月曜のとき」と読むと、この月は0日になります。
決まりとして書かれているのはPOSIX(The Open Group Base Specifications Issue 8 / IEEE Std 1003.1-2024)の crontab(新しいタブで開きます)です。原文はこうです。
Finally, if either the month or day of month is specified as an element or list, and the day of week is also specified as an element or list, then any day matching either the month and day of month, or the day of week, shall be matched.
同じ文書の例にも、はっきり書いてあります。0 0 1,15 * 1 は「毎月1日と15日に動き、そのうえ(as well as)毎週月曜にも動く」。 Linux の cron の説明書(crontab(5))も 「日の欄と曜日の欄がどちらも指定されていれば、どちらかが合ったときに実行される」と書いていて、30 4 1,15 * 5 を「毎月1日と15日の4時30分、加えて毎週金曜」 と説明しています。
では、どういうときに「かつ」になるのでしょうか。どちらかの欄が「*」のときです。 0 0 1 * * は曜日が「*」なので日づけだけで決まり、 0 0 * * 1 は日が「*」なので曜日だけで決まります。 つまり「*」は「なんでもよい」ではなく「この欄は使わない」という合図で、 両方を書いた瞬間に、2つの欄が足し算の関係に変わります。
ちなみに、0-6(日曜から土曜まで)と * は当たる曜日が同じ7つですが、 意味は違います。0 0 1 * 0-6 は「曜日を指定した」ことになるので OR に切り替わり、毎日動きます。 展開した値だけを見ていると、この違いは出せません。
この画面が「日と曜日だけ」を OR にしている理由。上の POSIX の文をそのまま読むと、月を指定しただけでも OR の側に入ってしまい、 0 0 * 3 1 が「3月の毎日」+「1年じゅうの毎週月曜」 になります。実際の cron はそう動きません。 Linux の crontab(5) は 「分・時・月が合い、かつ2つの日の欄のどちらかが合ったとき」と書いていて、月は必ず「かつ」です。ここは動いている cron に合わせています。
0 0 30 2 * は、永遠に動きません
2月30日は、どの年にも存在しません。だからこの式に当たる日は来ません。 cron は「近い日に寄せる」ことをしないので、3月2日に繰り上がったりもしません。エラーも出さず、ただ静かに動かないだけです。
4月31日・6月31日・9月31日・11月31日も同じです。 「毎月末に動かしたい」つもりで 0 0 31 * * と書くと、31日のある月だけ動いて、2月・4月・6月・9月・11月は飛ばされます。 月末は cron の5つの欄では書けないので、ふつうは翌月1日に動かして1日戻るか、コマンド側で日付を確かめます。
ただし曜日が指定されていれば話が変わります。 上に書いたとおり日と曜日は OR なので、 0 0 30 2 1 は「2月30日」に当たらなくても2月の月曜日で動きます。 「日づけが存在しないから動かない」と言い切れるのは、曜日の欄が「*」のときだけです。
探すのを9年で打ち切っている理由
次に動く日時は、日を1日ずつ試すという素朴なやり方で求めています。 当たる日が来ない式があるので、どこかで止めなければ永遠に探し続けます。
止める長さを9年にしたのには理由があります。0 0 29 2 *(2月29日)は、ふつうなら4年おきです。 ところが2100年はうるう年ではありません ── 100 で割り切れる年はうるう年から外れ、400 で割り切れる年だけが戻ってくるからです。 そのため2096年2月29日の次の2月29日は2104年で、8年あきます。 POSIX の5つの欄で書ける式のうち、間隔がいちばん長くなるのがこれです。 だから9年ぶん探して1件も無ければ、その式は永遠に動かないと言い切れます。
同じ「cron式」でも、方言がいくつもあります
cron 式という言葉は1つですが、欄の数も曜日の番号も違うものが並んで使われています。 貼り付けた式がどれの書き方なのかを間違えると、答えが丸ごとずれます。
| どこの | 欄 | 曜日の番号 | 日と曜日 |
|---|---|---|---|
| POSIXこの画面が使う定義 | 5分・時・日・月・曜日 | 0〜60が日曜 | どちらかに当たれば動く両方を指定したとき |
| cronieLinux の cron | 5POSIX と同じ | 0〜70も7も日曜 | どちらかに当たれば動くPOSIX と同じ |
| QuartzJava | 6〜7先頭に秒・末尾に年 | 1〜71が日曜 | 片方に「?」が要る両方は指定できない |
| SpringJava | 6先頭に秒 | 0〜70も7も日曜 | 「?」も書けるL・# もある |
| AWS EventBridgeクラウド | 6末尾に年 | 1〜71が日曜 | 片方は必ず「?」両方の指定は禁止 |
いちばん危ないのは曜日の番号です。POSIX は 0 が日曜なので、月曜が1・火曜が2と続きます。 Quartz と AWS は 1 が日曜なので、同じ「3」が火曜になります。数字は同じ、意味は2日ずれる ── 画面を見ても気づけません。
欄の数もそろっていません。Quartz と Spring は先頭に「秒」が増え、AWS EventBridge は末尾に「年」が増えます。 どちらも6個ですが増えた場所が逆なので、6個の式を5個として読むと全部ずれます。 だからこの画面は、6個の式を黙って読み替えずに、「どの方言のものか」を書いて止まります。
*/15 のようなスラッシュ(何おきか)も、じつはPOSIX にはありません。 POSIX が定めているのは「*」・数・範囲(1-5)・その並び(1,3,5)の4つだけです。 スラッシュは Vixie cron が足したもので、いまではほとんどの実装が持っています。 名前(MON や JAN)や @daily も同じく後から足されたものです。 この画面は読みますが、どこが拡張なのかをその場で名指しします。 黙って受け取るのでも、黙って断るのでもありません。
cron は「実行する機械の時計」で動きます
0 9 * * * と書いたとき、それが何時なのかは式だけでは決まりません。 cron は動かしている機械に設定された時間帯で時刻を読むので、サーバーが UTC なら、日本時間の18時に動きます。 9時間ずれるだけでなく、日付も1日ずれることがあります。
Linux の cron(cronie)には CRON_TZ という指定があり、その表だけ別の時間帯で読ませることもできます。 書いていなければ、機械の時間帯がそのまま使われます。
夏時間のある地域では、もう1つ落とし穴があります。 cronie の説明書は「夏時間の切り替えで存在しない時刻ができ、 その時刻に合う仕事は動かない。逆に二度来る時刻では2回動く」と書いています。 春に 2:30 が飛ぶ地域で 30 2 * * * と書いていると、その日は動きません。 日本には夏時間がありませんが、海外のサーバーではふつうに起きます。どこが何時なのかは世界時計と時差のページで確かめられます。
決まりの出どころ: 欄の並び・範囲・日と曜日が「どちらか」であることはPOSIX(The Open Group Base Specifications Issue 8 / IEEE Std 1003.1-2024)の crontab(新しいタブで開きます)、スラッシュ(何おきか)・名前・@daily・CRON_TZ・夏時間の注意はLinux の crontab(5)(新しいタブで開きます)、秒と年のある方言はQuartz の CronTrigger Tutorial(新しいタブで開きます)・Spring の CronExpression の javadoc・AWS EventBridge の資料(新しいタブで開きます)から取っています。計算はPOSIX の5つの欄だけで行っていて、? L W # を使う方言の計算はしていません。入れた式はこの画面の中だけで処理していて、 どこにも送っていません。