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 时间戳完全指南》。