手軽屋
ツール一覧

AWS・GCP・Cloudflare・VercelのcronはなぜUTCなのか

クラウドcronがUTC基準で動く理由、JSTで書きたい時の換算ルール、サービス別TZ設定の可否

1. なぜクラウドのcronはUTC基準なのか

主要なクラウドのcronスケジューラは、デフォルトで協定世界時(UTC)を基準に動きます。GitHub Actions、Cloudflare Workers cron triggers、Vercel Cron、AWS EventBridge(ScheduleExpression)、Google Cloud Scheduler のいずれもUTC基準。理由は分散システムが複数リージョン・複数データセンターにまたがって動作するため、ローカルタイムを基準にすると地域ごとに発火タイミングがずれて運用が破綻するから。UTCはサマータイム制度がなく、地球上のどこから見ても同一の時刻系列を保つため、分散システムの時刻基準として最適です。日本国内でしか動かさないアプリケーションであっても、クラウド側のcronスケジューラは設計思想としてUTC固定が安全です。JST 9時に動かしたいなら、UTC 0時(=「0 0 * * *」)を書く、という換算を毎回行う必要があります。

2. JST↔UTCの換算ルールと9時間の壁

JST(日本標準時)はUTC+9なので、JSTで書きたい時刻からUTCに変換するには「9時間引く」が原則。JST 9:00 = UTC 0:00、JST 12:00 = UTC 3:00、JST 18:00 = UTC 9:00、JST 0:00 = UTC 15:00(前日)。最後の例が日付境界の落とし穴で、JSTの0時はUTCでは前日の15時になります。これを意識せず「毎月1日のJST 0時に動かしたい」を「0 0 1 * *」と書くとUTC 1日0時 = JST 1日9時に発火し、9時間ずれる。正しくは「0 15 last-day-of-previous-month * *」となるが POSIX 5フィールドには「前月最終日」を表現する手段がないため、現実的にはジョブ側で日付チェックする実装になります。週次・月次・四半期次のジョブが日付境界をまたぐ可能性があるかを意識し、必要なら次の項のTZ設定で回避するのが安全。

3. TZを設定できるサービスとできないサービス

一部のクラウドサービスはcronスケジュールにタイムゾーンを設定できます。Google Cloud Scheduler は timeZone フィールドで IANA タイムゾーン名(Asia/Tokyo など)を指定可能。AWS EventBridge Scheduler(新しい方)も ScheduleExpressionTimezone でタイムゾーン指定可能。Kubernetes CronJob v1.27 以降は spec.timeZone フィールドが安定機能としてサポート。一方、GitHub Actions の schedule トリガーは公式仕様としてUTC固定で、TZ設定はできません。Cloudflare Workers cron triggers も2026年6月時点でUTC固定。Vercel Cron も同様にUTC固定。TZ設定不可のサービスでJSTで運用したい場合、cron式自体は UTC で書き、ドキュメントに JST 換算後の発火時刻をコメントとして残すのが現実的です。

4. 月跨ぎ・週跨ぎでハマる典型パターン

JST↔UTC換算でハマりやすいのが、月初・月末・週末をまたぐパターン。例: 「毎週月曜のJST 7時に通知」をUTCで書くと、UTC的には日曜の22時。cron式は「0 22 * * 0」となり、曜日が日曜(0)なのでパッと見「日曜実行」に見えて混乱します。実際には日本の月曜朝に発火しているが、cron式上は日曜と書く必要がある。同様に「毎月1日のJST 8時に集計」は UTC で「0 23 末日 * *」となり、月の最終日に発火することを意味するが、POSIX には「末日」を表す手段がないため、ジョブ側で日付チェックが必要になります。このような複雑性を避けるため、JST 9時以降(UTC換算で同じ日になる時間帯)にスケジュールを固定する運用パターンも実務でよく使われます。

5. サマータイム無しの日本は実は恵まれている

日本にはサマータイム(夏時間)制度がないため、JSTは年間通じてUTC+9で固定。これは実は運用上のメリットで、サマータイムを採用している米国・EU向けのcron運用と比べると、日付計算が安定します。例えば米国東部時間(ET)はEST(UTC-5)とEDT(UTC-4)が年2回切り替わり、サマータイム移行日には「23時間の日」「25時間の日」が発生してcronが想定外の動きをします。Google Cloud Scheduler や AWS EventBridge Scheduler の TZ 機能を使えばこの調整は自動ですが、UTC固定のcron式に書き直したい場合は移行日を意識した特別扱いが必要。日本国内で完結する運用なら、JST固定で考えてUTCに-9するだけで済むので比較的シンプル。海外サーバーで動かす場合のみ、サーバーのTZ設定(TZ=Asia/Tokyo 環境変数)を確認してください。

6. 運用ドキュメントに残すべき情報

クラウドcronを安全に運用するには、cron式そのものに加えてドキュメントに以下を明記すべきです。①意図する発火時刻のJST表記(例: 「毎日 JST 9時に実行」)、②実際のcron式(例: 「0 0 * * *」UTC)、③TZ設定(あれば: timeZone: Asia/Tokyo、なければ「UTC固定」)、④日付境界をまたぐ可能性(特に深夜実行ジョブ)、⑤次回発火日時の例(最初の数回分)。④と⑤を残しておくと、後任メンテナがcron式を読み解く時間を大幅に削減できます。本ツールで意図したJST時刻と実際の発火日時を照合してから、上記情報をREADMEやrunbookに転記する流れが実務的に効率的です。本ツールで次回10回分の発火日時を確認しドキュメントに転記してください。

手軽屋ツール実践手順

  1. JSTで希望する発火時刻を決める(例: 毎日朝9時)
  2. 9時間引いてUTCに換算(JST 9時 = UTC 0時)
  3. UTC換算後のcron式を書く(例: 「0 0 * * *」)
  4. cron式チェッカーに入力して次回日時シミュレーション
  5. 本ツールはJST表示するため、JST 9時で発火することを確認
  6. クラウド側のcron欄に貼り付け、ドキュメントにJST↔UTC両表記を残す

関連ツール

参照: Google Cloud Scheduler unix-cron scheduleKubernetes CronJob(timeZone field)POSIX crontab