Cron 表达式怎么读
Cron 是 Linux 和绝大多数任务调度系统用的定时语法。它由若干段用空格分开的字段组成,每一段描述一个时间维度。看懂它的关键不是背语法,而是搞清楚段与段之间是"与"的关系——所有字段同时满足,任务才执行。
五个字段分别是什么
- 第一段 分钟:0–59
- 第二段 小时:0–23,注意是 24 小时制,下午 3 点要写 15
- 第三段 日:1–31
- 第四段 月:1–12
- 第五段 星期:0–7,其中 0 和 7 都表示周日(有些实现里 1 才是周一,这点要注意)
如果调度系统支持秒级精度(比如 Spring 的 @Scheduled(cron=...)、Quartz),会在最前面多一段秒,变成 6 段。这也是为什么同一个表达式在不同地方粘贴会出现"跑得比预期频繁"的现象——明明是 5 段格式,系统却当成 6 段解析,整串字段就错位了。
五种写法
- 具体值:
30就表示第 30 分钟。 - 范围:
9-18表示从 9 到 18 都匹配,两端都包含。 - 列表:
1,3,5表示这三个值都行。 - 步长:
*/5表示从起始值开始每 5 个取一个;也可以写成10-40/5,表示从 10 到 40 之间每 5 分钟一次。 - 通配:
*表示"这一段随便",不做限制。
几种写法可以混着用,比如 0,30 9-17 * * 1-5 就是"周一到周五的 9 点到 17 点之间,整点和半点各跑一次"。
拆解一个真实的表达式
拿 */5 9-18 * * 1-5 举例,逐段看:
- 分钟
*/5:每 5 分钟(0、5、10…55) - 小时
9-18:上午 9 点到下午 6 点 - 日
*:不限日期 - 月
*:不限月份 - 星期
1-5:周一到周五
合起来就是:"工作日的 9:00 到 18:55 之间,每 5 分钟执行一次"。上班时段高频刷新数据、下班后停掉,是很常见的做法。
最容易踩的三个坑
- 「日」和「星期」同时限定时是「或」而不是「且」。 这是 Cron 里最反直觉的一条。写
0 0 13 * 5,本意可能是"13 号而且是周五",但实际含义是"每个月 13 号,或者每个周五"——频率高出十几倍。要表达"且"必须换思路,或者在脚本里自己判断。 - 别用
*/n跨过 24 点做精确周期。*/7在分钟位上其实是 0、7、14…56,然后下一小时又从 0 开始,所以 56 分钟之后只隔了 4 分钟。需要严格周期(比如每 7 分钟一次)应改用秒级字段或独立的调度器。 - 没有年份字段。 标准 Cron 管不了"只在 2026 年执行"。要限年份只能在任务脚本里判断,或者用支持年份的扩展语法(Quartz 支持,但标准 crontab 不支持)。
和 systemd timer 的区别
如果是新版 Linux,也可以用 systemd timer 替代 crontab。两者写法不同:crontab 直接一行写完,systemd 需要 .service 和 .timer 两个文件。systemd 的优势是支持 OnCalendar 这类更易读的格式、能记录上次执行结果、还能配置错过执行后的补偿策略(Persistent=true)。机器不是 24 小时开机的场景,systemd timer 更可靠——crontab 在关机期间错过的任务不会补跑。
另外要注意时区:Cron 用的是服务器本地时间。容器里默认多为 UTC,所以你在本地测好的"每天早上 8 点",上到容器可能变成下午 4 点。部署后一定要核对时区设置。
怎么验证一个表达式
别靠脑补。把这个表达式粘进上面的输入框,工具会列出接下来 10 次执行时间。看时间对不对是最快的验证方式——尤其能一眼看出"日和星期是或关系"这类坑:如果你写 0 0 13 * 5,列出的时间会同时包含每月的 13 号和每个周五,问题立刻暴露。
解析完全在浏览器本地完成,不需要联网。
常见问题
0 6 * * * 是几点?
每天早上 6 点整。第一段 0 表示第 0 分钟,第二段 6 表示 6 点,后面三段通配不限制。这是最常用的写法之一。
@daily 这类写法支持吗?
标准 crontab 支持一组宏:@daily(每天 0 点)、@hourly(每小时)、@weekly、@monthly、@yearly、@reboot(开机后执行一次)。本工具专注解析标准数字表达式,宏请自行等价替换,比如 @daily 就是 0 0 * * *。
为什么星期 7 也能用?
因为 0 和 7 都被定义为周日,写哪个都行。但如果要表达周一,请用 1——不要写 8。部分系统的星期定义是 1 到 7(1 为周日),跨平台迁移时务必确认。
预测的时间和实际执行时间不一致?
先查时区。容器、云函数默认多为 UTC,和北京时间差 8 小时。其次是确认调度器用的是 5 段还是 6 段格式——少写或多写一段,整串字段都会错位。
能算未来一年所有执行时间吗?
本工具默认列 10 次,足够校验逻辑。真要统计总量(比如评估任务压力),建议用调度系统自带的分析工具,或者自己在服务端算。