Cron 表達式生成器
可視化生成和解析 Cron 定時任務表達式
什麼是 Cron 表達式?
Cron 表達式用字串描述排程任務的重複執行時間。依排程器不同,它可能由五、六或七個欄位組成,分別表示分鐘、小時、日期、月份、星期,以及可選的秒和年份。星號、逗號、範圍、步進、問號和特殊佔位符可以表達「每 5 分鐘」、「工作日 9 點」、「每月最後一天」等規則。這個工具適合用來閱讀、檢查和預覽下一次執行時間,避免只靠記憶判斷。需要注意的是,Linux cron、Quartz、雲端排程器和框架在欄位數、時區處理與支援語法上可能不同。
使用方法
使用方式
- 選擇生成或解析模式
- 透過下拉選單設定時間欄位(秒、分、時、日、月、星期)
- 點選預設選項可快速填入常見表達式
- 生成模式會顯示表達式及未來 5 次執行時間
- 解析模式可驗證現有表達式並顯示執行時間
語法符號
- * — 所有可能的值
- , — 列舉多個值(例如:1,3,5)
- - — 範圍(例如:1-5)
- / — 步進間隔(例如:*/5 代表每 5 個單位)
- ? — 無特定值(用於日或星期欄位)
- L — 月份/星期的最後一天
- W — 最接近的工作日
- # — 當月第 N 個星期幾(例如:2#3 = 第三個星期二)
開發注意事項
- 將結果作為快速參考,然後在實際的程式碼、建置流程或 API 環境中進行測試。
- 需考慮版本、方言差異、環境變數及專案慣例。
重要提示
- 日與星期欄位不能同時有值,其中一個必須使用 ?
- 每個欄位都有有效範圍:分 0-59,時 0-23
- 欄位順序固定:秒 分 時 日 月 星期 年
- 星期幾不區分大小寫;MON 與 mon 視為相同
使用場景
技術原理
Cron 表達式以固定順序在各欄位中編碼零個或多個時間匹配約束。經典的 Vixie/BSD cron(Linux crond 使用)有 5 個欄位:分鐘(0-59)、小時(0-23)、日(1-31)、月(1-12 或 JAN-DEC)、星期(0-6 或 SUN-SAT,依慣例星期日 = 0)。Quartz 排程器(由 Spring 和 Egistix 函式庫推廣)在前面加上秒欄位共 6 個欄位,後面還可選加年份欄位共 7 個。每個欄位可以是字面值、列表(1,3,5)、範圍(1-5)、步進(0/15 表示從 0 開始每 15 單位)、或通配符 * 表示匹配所有值。問號 ? 是 Quartz 專用的哨兵值,表示「無特定值」,當日或星期其中一個有約束時,另一個必須使用 ?。 計算下一次 N 次執行時間採用貪婪前向搜尋演算法:從參考時刻(通常是現在)開始,遞增不匹配約束的最低層級欄位,將所有較低層級欄位重設為最小值,當欄位溢位時(例如分鐘超過 59、小時超過 23)向上級欄位進位。這稱為 Donovan/Spoonhour 迭代法,時間複雜度為 O(K x F),其中 K 是候選數量(通常為 5)、F 是欄位數。星期名稱(MON、FRI 等)會轉為小寫後匹配,月份名稱縮寫同樣接受。Quartz 中的 L 特殊字元表示該月最後一個指定星期幾(例如 0 0 0 ? * 5L 是最後一個星期五),計算方式是從該月最後一天往前數找到指定的星期幾。W 字元找到距離給定日最近的工作日(週一至週五),必要時會跨到鄰近月份。 時區設定是最常見的錯誤來源:表達式本身不帶時區資訊,因此相同的 0 0 9 * * ? 在 America/New_York、Asia/Tokyo 和 UTC 的伺服器上會在不同的 UTC 偏移時間觸發。簡寫如 @daily(0 0 0 * * ?)、@hourly(0 0 * * * ?)、@reboot(守護程式啟動時執行一次,不是時間表達式)、@weekly(0 0 0 ? * 1)會在解析前展開為等效的 6 欄位形式。一個常見陷阱是日與星期的組合邏輯:在經典 cron 中任一匹配即執行(OR 邏輯),而一些較新的方言改為 AND 邏輯。表達式 0 0 0 15 * 5 在 Vixie cron 中表示「15 號午夜且每個星期五」執行,而非許多初學者以為的「15 號午夜或星期五」。Y2038 問題不會直接影響 cron(它使用 time_t),但任何執行 32 位元 Unix crond 的嵌入式裝置將在 2038-01-19T03:14:07Z 溢位有符號 32 位元 time_t 整數。
- 經典 5 欄位:分 時 日 月 週;Quartz 新增秒(6 欄位)和可選的年份(7 欄位)。
- ? 必須在日或星期其中一個有值時佔據另一個欄位;* 匹配該欄位的所有值。
- 日 + 星期在 Vixie cron 中是 OR 邏輯,在部分較新排程器中是 AND 邏輯——部署前請確認。
- L 表示該月最後一個指定星期幾:例如 0 0 0 ? * 5L = 最後一個星期五,由月份天數計算。
- W 找到距離給定日期最近的工作日(週一至週五);可能跨入鄰近月份。
- Cron 表達式不帶時區資訊:同一表達式在伺服器本地時間、UTC 或命名時區下觸發時間不同,取決於排程器。
- Y2038:32 位元 time_t 將在 2038-01-19 03:14:07 UTC 溢位;傳統嵌入式系統上的 crond 將受影響。
- 簡寫 @hourly/@daily/@midnight/@weekly/@monthly/@yearly/@reboot 展開為等效的 5 欄位或 6 欄位表達式。
- 步進 / 運算子從最左值開始計數:小時欄位的 2/3 在 2、5、8、11、14、17、20、23 觸發。
- 以 O(KxF) 的五次迭代貪婪前向搜尋從參考時刻計算下 N 次執行時間。
範例
每天午夜(每日備份)
Expression : 0 0 * * *
Means : 每天 00:00
Next runs : 2026-06-11 00:00, 2026-06-12 00:00, 2026-06-13 00:00
Use case : 資料庫備份、每日報表產生每 15 分鐘執行一次(健康檢查)
Expression : */15 * * * *
Means : 每小時的第 0、15、30、45 分鐘
Next runs : 14:00, 14:15, 14:30, 14:45, 15:00
Use case : API 健康檢查、佇列輪詢、同步任務週一至週五上午 9:00(上班時段提醒)
Expression : 0 9 * * 1-5
Means : 週一到週五 09:00
Next runs : Mon 09:00, Tue 09:00, Wed 09:00, Thu 09:00, Fri 09:00
Use case : 站立會議提醒、Slack 每日摘要每月 1 日 03:30(月度帳單)
Expression : 30 3 1 * *
Means : 每月 1 日 03:30
Next runs : Jul 1 03:30, Aug 1 03:30, Sep 1 03:30
Use case : 月度發票產生、日誌輪替、封存每週日午夜(每週清理)
Expression : 0 0 * * 0
Means : 每週日 00:00(在 Linux cron 中 0 = 週日)
Next runs : Sun 00:00, Sun 00:00, Sun 00:00
Use case : 週報郵件、快取清除、模型重新訓練Quartz 含秒位 — 每 30 秒一次
Expression : */30 * * * * ?
Means : 每 30 秒一次(6 欄位 Quartz 語法)
Next runs : 14:00:00, 14:00:30, 14:01:00, 14:01:30
Note : 因為 day-of-month 為 *,所以 day-of-week 必須是 ?。此格式須用 Quartz,不可用 Linux cron。常見問題
支援哪些 cron 格式?
標準 5 欄位 cron(分 時 日 月 週)、6 欄位含秒(Quartz、Spring 與許多雲端排程器使用)、以及 7 欄位含可選年份。頁面可以選格式,編輯運算式時會解說每個欄位。
為什麼日(dayOfMonth)和週(dayOfWeek)會同時是欄位?
標準 cron 把它們視為 OR:「每月 1 日 OR 每個星期一」兩個條件任一成立就會觸發。要做 AND 通常需要非標準的 ? 語法(Quartz)或繞道實作。頁面會顯示接下來幾次觸發時間,你可以用視覺確認預期是否正確。
排程真的會在我的系統上跑嗎?
不會——頁面只負責產生並驗證運算式,工作是在你的排程器裡執行(Linux cron、GitHub Actions、Kubernetes CronJob、AWS EventBridge、Quartz 等等)。各家排程器的 cron 方言略有不同,請依目標平台選對格式。
排程使用什麼時區?
標準 Unix cron 使用系統當地時區。雲端排程各家不同——AWS EventBridge 預設 UTC,GitHub Actions 預設 UTC,Kubernetes CronJob 採 API 伺服器的時區。請查閱所用排程器的文件,並注意 DST 切換可能讓任務在意想不到的時間觸發。
「每 30 分鐘」要怎麼寫?
*/30 * * * *(分鐘 = 0,30;每小時、每天、每月、每週都成立)。「只在工作時間內每 15 分鐘」可以寫成 */15 9-17 * * 1-5(限定週一到週五 9-17 點)。頁面會列出接下來 5-10 次觸發時間供確認。
拿來跑正式環境的排程安全嗎?
頁面只產生運算式,實際執行交給你的排程器。先用樣本跑一次驗證(多數排程器有「手動執行」選項),並且避免把任務排在午夜 00:00,那是許多系統任務扎堆、容易爆量的時段。
有任何資料會上傳嗎?
不會。運算式的解析以及下次觸發時間的計算都在你的瀏覽器中,使用 JavaScript 的 cron 函式庫完成。