5 分钟看懂 Cron 表达式

· 约 1 分钟 Cron

第一次看到 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 次执行时间”是不是你想要的。尤其是带步长和范围的复杂表达式,肉眼容易看错。

❓ 常见问题

Cron 表达式最细可以到多少粒度?

Linux crontab 最细是"分钟",没有秒级。Spring 和 Quartz 支持秒级(6 位或 7 位格式)。要更细粒度(比如每 10 秒)在 Linux 上只能改用 systemd timer 或 while 循环。

为什么 `* * * * *` 不是每秒执行?

Linux cron 的 5 个字段分别是分/时/日/月/周,没有秒字段。`* * * * *` 是每分钟执行,最快就是每分钟一次。想要每秒执行要用 Spring 6 位格式 `* * * * * *`,或者 systemd timer。

怎么判断是 Linux 还是 Spring 格式?

数字段数量就够了——5 位是 Linux/crontab,6 位是 Spring,7 位是 Quartz。另外 Quartz 的日和周字段必须有一个是 `?`,这是它独有的语法。

"每月最后一天"怎么表达?

Linux cron 做不到——`0 0 28-31 * *` 会在 28/29/30/31 号都执行。Quartz 支持 `L`(Last)专门表示最后一天。Linux 下只能在脚本里判断 `[ $(date -d tomorrow +%d) = 01 ]`,成立才执行。

打开 Cron 解析 · 可视化生成 · 示例库

📖 同一工具的其他教程