第一次看到 0 */5 * * * 都会懵一下——这到底是”每 5 分钟”还是”每小时的第 5 分”?搞清楚 Cron 表达式其实只需要理解两件事:字段顺序,和通配符含义。
字段顺序
Linux crontab 用 5 个字段,顺序从小到大:
分 时 日 月 周
* * * * *
Spring 调度器多一个”秒”字段,在最前面:
秒 分 时 日 月 周
* * * * * *
Quartz 再多一个”年”字段(可选,放最后),共 7 个字段。
记忆法:Linux 5 字段、Spring 6 字段、Quartz 7 字段,多出来的分别是”秒”和”年”。
5 个通配符
| 符号 | 含义 | 例子 |
|---|---|---|
* | 任意值 | * * * * * 每分钟执行 |
, | 列举 | 0 8,12,18 * * * 每天 8 点、12 点、18 点 |
- | 范围 | 0 9-17 * * 1-5 工作日 9-17 点每小时 |
/ | 步长 | */15 * * * * 每 15 分钟 |
? | 占位(仅 Quartz 的日/周字段) | 避免日和周冲突 |
常见场景速查
0 0 * * * 每天 0 点
0 */6 * * * 每 6 小时
0 9 * * 1-5 工作日早 9 点
*/10 * * * * 每 10 分钟
0 0 1 * * 每月 1 号 0 点
0 0 * * 0 每周日 0 点
一个经典坑:日和周
Linux cron 里 0 0 1 * 1 的意思是**“每月 1 号 0 点,或者每周一 0 点”——日和周是或**的关系,不是与。如果你想表达”每月第一个周一”,cron 原生做不到,需要在脚本里自己判断。
Quartz 用 ? 解决这个歧义:日和周字段必须有一个是 ?。
调试建议
写完 Cron 别直接上生产——先丢进解析器,看看它列出的”未来 5 次执行时间”是不是你想要的。尤其是带步长和范围的复杂表达式,肉眼容易看错。