Cron 表达式速查表:语法、示例与五个高频错误
最后更新:2026-09-14
Cron 表达式用一个短字符串描述「什么时候执行」。它足够简单,但也足够容易写错——尤其是想表达「每月最后一个工作日」这类需求时。
这篇速查先讲清字段与符号,再列出可直接复制的常用示例,最后集中处理最容易出错的几个地方。
一、五段式与六段式
传统 crontab 是五段:分、时、日、月、周。部分调度框架(如 Quartz)在开头增加秒位,变成六段。写表达式前第一件事就是确认目标平台用哪种——多写一位或少写一位,语义会完全错位。
注意「日」与「周」同时被限定时,传统 cron 取的是或关系(满足任一即执行),而多数现代框架取与关系。这是跨平台迁移时最容易被忽略的语义差异。
二、字段取值范围
- 分:0–59
- 时:0–23(24 小时制,没有 AM/PM)
- 日:1–31
- 月:1–12 或英文缩写 Jan–Dec
- 周:0–6(0 与 7 通常都表示周日)或 Sun–Sat
- 秒(若有该字段):0–59
三、特殊符号
*任意值,表示该字段的每个取值都匹配;,枚举,如1,15表示 1 号与 15 号;-区间,如9-17表示 9 点到 17 点;/步长,如*/5表示每 5 个单位一次;?不指定(仅部分框架支持,用于日/周字段);L最后一天或最后一个(如最后一个周五);W最近的工作日;#第几个,如5#2表示第二个周五。
四、可直接复制的常用示例
- 每分钟:
* * * * * - 每 5 分钟:
*/5 * * * * - 每小时整点:
0 * * * * - 每天 0 点:
0 0 * * * - 每天 3 点 30 分:
30 3 * * * - 每天 8 点与 20 点:
0 8,20 * * * - 工作日 9 点到 18 点每小时:
0 9-18 * * 1-5 - 每周一 0 点:
0 0 * * 1 - 每月 1 号 0 点:
0 0 1 * * - 每月 1 号与 15 号 0 点:
0 0 1,15 * * - 每季度首月 1 号:
0 0 1 1,4,7,10 * - 每 30 分钟且只在工作日:
*/30 * * * 1-5 - 每天 2 点与 14 点各一次:
0 2,14 * * * - 每 2 小时:
0 */2 * * * - 每年 1 月 1 日 0 点:
0 0 1 1 *
五、五个高频错误
- 时区不符:容器与宿主机的时区默认往往是 UTC。你写的「每天 0 点」在 UTC 下执行,落在北京时间上午 8 点。务必显式设置调度器的时区,而不是依赖宿主机;
- 把日与周一起限定:写
0 0 1 * 1想表达「每月 1 号且是周一」,传统 cron 实际表达的是「每月 1 号或每周一」,执行次数远超预期; - 步长与范围混用出错:
0 9-17/2 * * *的含义是从 9 点起每 2 小时,得到 9、11、13、15、17 点,而不是「上午 9 点到 17 点之间偶数点」的直觉理解; - 用 31 号做月末任务:2 月没有 31 号,该任务在 2 月直接不执行。月末任务的正确写法需要依赖框架的 L 支持,或改为「每月 1 号执行上月结账」;
- 表达式写对但任务堆叠:每分钟一次的任务如果单次执行超过一分钟,会不断堆积。调度器通常不会阻止并发,需要在任务内部加锁或加超时。
六、写完一定要验证执行时间
Cron 表达式的错误几乎都能靠「未来几次执行时间」看出来。用 Cron 表达式解析工具 输入表达式后核对接下来的执行时刻,是成本最低的验证方式——尤其是涉及月末、工作日、步长的复杂表达式。
与时间相关的其他陷阱(夏令时、时间戳单位)见《Unix 时间戳完全指南》。