GitHub Actions の cron を日本時間で動かす|UTC 変換の早見表と曜日ずれ・遅延の対策
GitHub Actions の schedule に「0 9 * * 1-5」と書いたのに、ワークフローが動いたのは日本時間の夕方 6 時だった。これは書き間違いではなく、GitHub Actions の cron が必ず UTC(協定世界時)で読まれるためです。この記事では、日本時間(JST)の時刻を UTC の cron 式に直す計算と早見表、朝 0〜8 時を指定したときに起きる「曜日・日付が前の日にずれる」問題、1 行で書けないときの 2 行への分け方、そして schedule が遅れる・動かないときの原因と対策までをまとめます。
なぜ 9 時間ずれる?GitHub Actions の cron は UTC 固定
GitHub Actions では、ワークフローの YAML に on.schedule と cron 式を書くと、決まった時刻にジョブを動かせます。このとき cron 式は、リポジトリの持ち主がどの国にいても、ランナーがどこにあっても、UTC(協定世界時)の時刻として読まれます。パソコンの時計やリポジトリの設定に合わせて日本時間に読み替えてくれることはありません。
日本時間(JST)は UTC より 9 時間進んでいます。つまり UTC の 0:00 は日本の 9:00、UTC の 9:00 は日本の 18:00 です。日本時間のつもりで「0 9 * * *」と書くと、UTC の 9:00、すなわち日本時間の 18:00 に動きます。冒頭の「夕方 6 時に動いた」はまさにこのパターンです。
- 日本時間 → UTC:時から 9 を引く(9:00 → 0:00、18:30 → 9:30)
- 引いた結果がマイナスになる(日本時間の 0〜8 時)ときは、24 を足して「前の日」の時刻にする(8:00 → 前日 23:00)
- UTC → 日本時間:時に 9 を足す。24 以上になったら 24 を引いて「次の日」にする
- 日本には夏時間がないので、季節によって時差が変わることはない(常に 9 時間)
日本時間 → UTC の cron 式 早見表
よく使う時刻を、日本時間で書いたときの cron 式と、GitHub Actions に書くべき UTC の cron 式で並べました。右の列をそのまま - cron: に貼れば、日本時間の左の時刻に動きます(実際には後で説明する遅延が加わります)。
| 動かしたい時刻(日本時間) | 日本時間の cron 式 | GitHub Actions に書く式(UTC) |
|---|---|---|
| 毎日 9:00 | 0 9 * * * | 0 0 * * * |
| 毎日 8:30 | 30 8 * * * | 30 23 * * *(前日の 23:30) |
| 毎日 18:00 | 0 18 * * * | 0 9 * * * |
| 毎日 0:00(日付が変わったら) | 0 0 * * * | 0 15 * * *(前日の 15:00) |
| 平日(月〜金)9:00 | 0 9 * * 1-5 | 0 0 * * 1-5 |
| 平日(月〜金)8:00 | 0 8 * * 1-5 | 0 23 * * 0-4(日〜木の 23:00) |
| 平日(月〜金)6:00 | 0 6 * * 1-5 | 0 21 * * 0-4(日〜木の 21:00) |
| 平日 9〜18 時の毎時 0 分 | 0 9-18 * * 1-5 | 0 0-9 * * 1-5 |
| 毎週月曜 0:00 | 0 0 * * 1 | 0 15 * * 0(日曜の 15:00) |
| 2 時間ごと(0・2・4…時) | 0 */2 * * * | 0 1-23/2 * * * |
| 毎月 15 日 9:00 | 0 9 15 * * | 0 0 15 * * |
| 毎月 1 日 3:00 | 0 3 1 * * | 1 行では正確に書けない(後述) |
表の中で注意したいのは、日本時間の 0〜8 時を指定している行です。時刻を 9 時間戻すと前の日になるため、時だけでなく曜日や日付も 1 つ戻さなければいけません。「平日 8:00」を「0 23 * * 1-5」と時だけ直してしまうと、UTC の月〜金の 23:00、つまり日本時間の火〜土の 8:00 に動いてしまい、月曜の朝に動かず土曜の朝に動く、というずれが起きます。
「2 時間ごと」も見落としやすい例です。日本時間の 0・2・4…22 時は、UTC では 15・17・19・21・23・1・3…13 時と奇数の時刻になるため、「*/2」のままでは 1 時間ずれます。UTC で奇数の時刻を表す「1-23/2」に書き換える必要があります。
朝 0〜8 時は「前の日・前の曜日」になる:ずれの計算方法
日本時間を UTC に直すとき、日付が変わるかどうかは「時」だけで決まります。日本時間の 9 時以降なら同じ日のまま、0〜8 時なら前の日になります。曜日・日付の欄を直す手順は次のとおりです。
- 1
時から 9 を引く
8:00 なら 8 − 9 = −1。マイナスになったら 24 を足して 23 にし、「前の日にずれる」と覚えておきます。9 以上なら引いた値をそのまま使い、日付はずれません。
- 2
曜日の欄を 1 つ戻す
前の日にずれる場合、曜日の数字から 1 を引きます。月〜金(1-5)は日〜木(0-4)に、月曜(1)は日曜(0)に、日曜(0)は土曜(6)になります。曜日が * なら直す必要はありません。
- 3
日の欄を 1 つ戻す
日付で指定しているときも同じく 1 を引きます。15 日なら 14 日です。ただし 1 日を戻すと「前の月の末日」になり、末日は 28〜31 日と月によって変わるため、cron の 1 行では正確に書けません。
- 4
次の実行日時で確かめる
直した式の次の実行日時を日本時間で 10 件ほど並べ、元の意図(月曜の朝 8 時に動く、など)と一致しているかを確認します。手計算のミスはここで見つかります。
この計算は、時刻が 1 つだけなら暗算でもできますが、複数の時刻・曜日・日付が組み合わさると急に間違えやすくなります。cron 式チェッカーの「日本時間→UTC 変換」では、日本時間の式を入れると曜日・日付のずれまで含めた UTC の式を出し、変換前と変換後の次の 40 回の実行時刻が一致するかを自動で照合します。
1 行で書けないときは - cron: を 2 行に分ける
日本時間の「平日の 7:00 と 12:00」のように、9 時より前の時刻と後の時刻が混ざっていると、UTC に直したときに 7:00 だけが前の日にずれます。前の日にずれる時刻とずれない時刻では曜日の欄が違うため、1 つの cron 式にまとめることができません。
| 日本時間の時刻 | UTC の時刻 | 曜日の欄 | GitHub Actions に書く式 |
|---|---|---|---|
| 平日 12:00 | 3:00(同じ日) | 1-5 のまま | 0 3 * * 1-5 |
| 平日 7:00 | 22:00(前の日) | 0-4 に戻す | 0 22 * * 0-4 |
GitHub Actions の on.schedule には cron を複数並べられるので、このようなときは「- cron: '0 3 * * 1-5'」と「- cron: '0 22 * * 0-4'」の 2 行に分けて書きます。どちらかの時刻に当てはまればワークフローが動きます。ジョブの中でどちらの時刻で動いたかを知りたいときは、github.event.schedule に、そのとき動いた cron 式の文字列が入っているので、if 条件で分岐できます。
schedule が遅れる・動かないときの原因と対策
時刻を正しく UTC に直しても、GitHub Actions の schedule は「指定した時刻ちょうど」には動かないことがあります。GitHub のドキュメントでも、負荷の高い時間帯には遅れることや、混雑時にはキューに入ったジョブが破棄されることがあると説明されています。よくある原因を整理しておきます。
| 症状 | 原因 | 対策 |
|---|---|---|
| 毎回 5〜30 分ほど遅れる | 毎時 0 分は世界中の schedule が集中する | 分を 0 以外(例: 17 分や 43 分)にずらす |
| ときどき 1 回分が丸ごと動かない | 混雑時にキューから落とされることがある | 取りこぼしても困らない処理にする・重要な処理は別の仕組みも検討 |
| 「*/1」「*/3」でも 5 分おきにしか動かない | schedule は最短 5 分間隔 | 5 分未満の間隔が必要なら別のスケジューラーを使う |
| ブランチに置いたのに動かない | schedule はデフォルトブランチの最新コミットのファイルだけが対象 | main(デフォルトブランチ)にマージする |
| しばらく放置したら止まった | 公開リポジトリは 60 日間アクティビティがないと schedule が無効になる | Actions のタブからワークフローを再度有効にする |
| フォークでは動かない | フォークしたリポジトリでは Actions が無効になっていることが多い | フォーク側の Actions を有効にする |
特に効果が大きいのは「分をずらす」ことです。毎日 9:00 ちょうどである必要がなければ、日本時間 9:17 にあたる「17 0 * * *」のように書くだけで、0 分の集中を避けて遅れが目に見えて小さくなります。逆に、営業開始前に必ず終わっていてほしい処理は、遅れを見込んで 30 分〜1 時間早めに設定しておくと安心です。
設定したら確かめる:手動実行と次の実行日時のチェック
schedule は、次の時刻が来るまで正しく動くかどうかが分かりません。日次や週次のワークフローだと、ミスに気づくまで何日もかかります。push する前後で、次の 3 つを確かめておくと手戻りが減ります。
- on: に workflow_dispatch: も足しておき、Actions のタブから手動で実行してジョブの中身が成功するかを先に確かめる
- cron 式チェッカーで GitHub Actions を選んで式を貼り、次の実行日時を日本時間で並べて、曜日と時刻が意図どおりかを見る
- 初回の実行が終わったら、実行履歴の時刻(UTC)に 9 時間足して、想定した日本時間に動いたかを照らし合わせる
cron 式そのものの書き方(5 つの欄や */5 などの記号)に自信がない場合は、crontab の書き方と早見表で基本を確認できます。「毎月第 2 月曜」や「月末」のように GitHub Actions の cron だけでは書きにくい指定は、cron の日と曜日の OR と第 n 曜日・月末の書き方で、コマンド側で日付を確かめる方法を紹介しています。AWS で同じことをする場合はEventBridge の cron 式の書き方を参照してください。
よくある質問
- GitHub Actions の cron で日本時間の 9 時に動かすには?
- GitHub Actions の cron は UTC で読まれるので、日本時間から 9 時間引いた UTC の 0:00 を指定します。毎日なら「0 0 * * *」、平日だけなら「0 0 * * 1-5」です。日本時間の 9 時以降は日付も曜日もずれないので、時から 9 を引くだけで済みます。
- GitHub Actions の schedule でタイムゾーンを日本時間に設定できますか?
- cron 式は UTC として読まれるため、日本時間の時刻を UTC に直して書くのが基本です。ジョブの中で使う日付や時刻だけを日本時間にしたい場合は、ステップやジョブの環境変数に TZ: Asia/Tokyo を設定します。これは date コマンドなどの表示に効くもので、スケジュールの時刻は変わりません。
- 日本時間の朝 8 時を UTC にすると曜日はどうなりますか?
- 日本時間の 8:00 は UTC の前日 23:00 なので、曜日も 1 つ前に戻します。平日(月〜金)の 8:00 なら UTC では日〜木の 23:00 で、「0 23 * * 0-4」と書きます。時だけ直して「0 23 * * 1-5」とすると、日本時間の火〜土の朝に動いてしまいます。
- GitHub Actions の schedule が時間どおりに動かないのはなぜですか?
- 毎時 0 分は世界中のワークフローが集中するため、数分〜数十分遅れたり、混雑時には実行が飛ばされたりすることがあります。分の欄を 0 以外(17 分など)にずらすと遅れにくくなります。また、schedule はデフォルトブランチのファイルだけが対象で、公開リポジトリは 60 日間更新がないと無効になる点も確認してください。
- GitHub Actions の cron で 1 分ごとに動かせますか?
- できません。schedule で動かせる最短の間隔は 5 分です。「* * * * *」や「*/1 * * * *」と書いても、5 分より短い間隔では実行されません。分単位の監視などが必要な場合は、外部の監視サービスや常駐するサーバーの cron など、別の仕組みを使います。
この記事で紹介したツール
あわせて読みたい
crontab の書き方と早見表|5 つの欄と記号の意味・よく使う例・登録のコマンド
「毎日 3 時にバックアップ」「5 分ごとに監視スクリプト」のような定期実行は、Linux では crontab に 1 行書くだけで設定できます。ただ、「分 時 日 月 曜日」の 5 つの欄と、* , - / という記号の組み合わせは、慣れないうちは読み間違えやすく、1 時間に 60 回動いてしまったり、7 分おきのつもりが 4 分おきになったりといった事故も起きがちです。この記事では、crontab の書き方の基本と記号の意味、そのまま使える早見表、crontab -e・-l・-r の使い方、コマンド部分を書くときの注意点までを、例を中心に解説します。
記事を読む →cron が動かない原因チェックリスト|手動では動くのに失敗する理由とログの確認方法
crontab に書いたはずのバッチが動いていない。ターミナルで手で実行すると成功するのに、cron からだと何も起きない。cron のトラブルは、エラーがどこにも表示されないまま静かに失敗することが多く、原因を探すのに時間がかかりがちです。この記事では、cron が動かないときに確かめる順番を「式」「cron 本体」「ログ」「実行環境」「ファイルと権限」「タイムゾーン」に分けて整理し、手動では動くのに cron だと失敗する典型的な理由と、その直し方をまとめます。
記事を読む →EventBridge の cron 式の書き方|? の意味・曜日の数字・日本時間の指定と crontab からの書き換え
AWS で Lambda や ECS のタスクを定期実行するときに使う EventBridge の cron 式は、Linux の crontab と似ているようで、欄の数・? の使い方・曜日の数字・タイムゾーンが少しずつ違います。crontab の感覚で「0 9 * * 1-5」と書くとエラーになり、曜日の数字をそのまま移すと 1 日ずれ、時刻は UTC で読まれて 9 時間ずれる、とつまずきどころが重なります。この記事では、EventBridge の cron 式の 6 つの欄と ? のルール、曜日の数字、L・W・# の使い方、rate 式との違い、ルールと Scheduler での日本時間の扱い、crontab・Kubernetes・Spring・systemd との書き換え表までをまとめます。
記事を読む →