跳到主内容
d.devtul.fun
定时任务 · 2026-09-20

Cron 表达式入门:五个字段读懂定时任务

Cron 表达式最常见的形式是五个字段,用空格分开:

┌───── 分钟 (0-59)
│ ┌───── 小时 (0-23)
│ │ ┌───── 日   (1-31)
│ │ │ ┌───── 月   (1-12)
│ │ │ │ ┌───── 星期 (0-6,0 = 周日)
│ │ │ │ │
* * * * *

关键在于:这五个字段之间是"与"的关系,一个时间点只有在五个字段全部匹配时才会触发。

每个字段能写什么

写法含义例子
*任意值小时写 * = 每小时
5具体值分钟写 5 = 每小时的第 5 分钟
1-5范围星期写 1-5 = 周一到周五
1,15枚举日写 1,15 = 每月 1 号和 15 号
*/10步长分钟写 */10 = 每 10 分钟
9-17/2范围内步长小时写它 = 9 到 17 点之间每隔 2 小时

几个常见表达式

0 * * * *        每小时整点
*/5 * * * *      每 5 分钟
0 3 * * *        每天凌晨 3:00
0 3 * * 0        每周日凌晨 3:00
0 0 1 * *        每月 1 号零点
30 9 * * 1-5     工作日 9:30
0 */6 * * *      每 6 小时

最容易踩的坑:日与星期的"或"

这是 Cron 里最反直觉的一条规则。当日和星期两个字段都不是 * 时,大多数实现(包括经典的 Vixie Cron 和大多数 Linux 发行版)会变成"或"的关系,而不是"与"。

0 0 1 * 1

直觉上会读成"每月 1 号且是周一的零点",但实际含义是"每月 1 号,或者任意一个周一"。想表达"每月 1 号且是周一",只能把其中一个字段设为 *,然后在脚本里自己判断。

这条规则每年都会坑到一批人,尤其是写账单、报表这类对日期敏感的任务时。

另一个坑:时区

Cron 用的是服务器本地的时区。同一份配置放在不同机房,触发时间可能差好几个小时。夏令时切换的日子里,被跳过的那个小时内的任务可能整天都不执行。

如果对时间精度有要求,要么把服务器时区统一成 UTC 并做好换算,要么改用支持显式指定时区的调度系统。

怎么验证自己写对了

最直接的办法是看它接下来会怎么触发。Cron 表达式工具 会把你写的表达式翻译成中文说明,并列出未来 8 次触发时间 —— 上面那个 0 0 1 * 1 到底什么时候跑,一眼就看得出来了。

继续阅读