跳到正文
DevTools / Cron 表达式解析

Cron 表达式解析

cron 表达式是五到六段简洁的标点,决定着任务何时运行;写错的后果通常要等到任务从不触发、或触发的频率远超预期时才被发现。本解析器用文字解释每个字段,把接下来若干次执行时间按你选择的时区渲染成真实日期,提示那些会静默跳过或重复执行的夏令时切换点,并说明各 cron 实现之间语法扩展的差异。

完全在浏览器本地运行——不会上传任何内容。

含义

at minute */15 of hour 9-17, on 1 through 5.

字段原始取值范围类型解释
Minute*/150–59stepevery 15 minutes
Hour9-170–23range9 through 17
Day of month*1–31wildcardevery value
Month*1–12wildcardevery value
Day of week1-50–7range1 through 5
后续执行时间 — 浏览器时区
标记的时间落在夏令时切换附近,实际执行时刻可能被跳过或重复。
语法说明
  • * — 任意值
  • */5 — 步长
  • 1-5 — 范围
  • 1,15 — 列表
  • 9-17/2 — 范围加步长
  • L — 当月最后一天
  • 1#2 — 当月第 n 个星期几
  • MON-FRI — 月份与星期支持英文三字母缩写

工作原理

五个字段依次是分钟、小时、日、月、星期。每个字段都接受单个值、逗号分隔的列表、连字符表示的范围,以及斜杠表示的步长——因此分钟字段里的 */15 表示每十五分钟。星号是通配符,表示该字段范围内的每一个取值。当“日”和“星期”都不是通配符而都被限定时,标准 cron 把它们视为并集:只要任一匹配任务就会运行,而不是两者都要满足。这一条规则是“任务执行得比作者预期更频繁”最常见的成因。

非标准语法正是可移植性崩塌的地方。Java 的 Quartz 采用六到七个字段、秒在最前,并支持 L(最后一天)、W(最近的工作日)和 #(当月第几个星期几)。AWS EventBridge、Kubernetes CronJob、systemd timer 和 Vixie cron 都各有细微差异:有的接受 @daily、@reboot 之类的宏,有的接受六字段带秒的形式,有的并不在每个字段都支持步长。一个什么都接受的解析器,会在你的目标调度器实际上会拒绝、或者会做不同解释时告诉你表达式合法。

星期编号自身就是一个陷阱。Vixie cron 和多数 Unix 实现把周日编为 0,因此 0 和 7 都表示周日;Quartz 把周日编为 1,于是两套系统在每一天上都相差一。在错误的约定下,按周一写的 1 会在周日运行,而由于两种解释都说得通,这个错误往往能挺过代码评审。凡是支持 SUN、MON、TUE 这类名称的地方,使用名称就彻底消除了歧义,应当优先采用。

夏令时是一年只出现两次的故障。在向前拨钟的时区里,定于切换日 02:30 的表达式指向一个并不存在的时刻,各实现对它的反应并不一致:有的跳过本次执行,有的在平移后的时刻执行,有的执行两次。在向后拨钟的那次切换中,01:30 这个小时会出现两次,定于此时的任务可能执行两次或一次,取决于实现。本工具会把落在切换点前后一小时内的后续执行时间标出来,让风险在编写表达式时就被看见,而不是等某份季度报表少了一天之后。

常见应用场景

  • 在修改之前,弄清服务器 crontab 里某个 cron 表达式到底做什么。
  • 为夜间任务编写表达式,并确认接下来的执行时间确实落在预期时刻。
  • 把“每个工作日早上 9 点”这类需求翻译成正确的表达式。
  • 排查某个任务为何一年中有一天会执行两次——通常是夏令时切换。
  • 确认表达式的星期编号与目标调度器所期待的一致。
  • 按同事所在时区核对接下来的若干次执行时间,用于交接或值班轮换。

最后更新: 2026-10-14

常见问题解答

第五个字段是“日”还是“星期”?

五个字段依次是分钟、小时、日、月、星期,因此第三个是日,第五个是星期。常见混淆源于两者都能限定调度时间,而且它们会相互作用:当两者都被限定时,标准 cron 在任一匹配时就会执行,所以 0 0 13 * 5 会在每月 13 日以及每个周五运行。把其中之一设为通配符,是避免这种意外的常用做法。

为什么夏令时切换时任务会执行两次或干脆不执行?

因为本地挂钟时间可能被跳过或被重复。向前拨钟时,落在被跳过的那一小时内的表达式指向一个永不发生的时刻,实现要么跳过本次执行,要么在平移后的时刻触发。向后拨钟时,同一个挂钟小时出现两次,任务可能被视为两次都到期。改用 UTC 运行定时任务可以彻底避开该问题,代价是调度时间不再跟随当地办公时间。

星期字段里的 0 和 7 有什么区别?

在标准 Unix cron 实现里两者都表示周日,它把周日编为 0 并允许把 7 当作同义词。Quartz 把周日编为 1,于是每一天都向后移一位,本想定在周一的表达式会在周日运行。由于两种约定都广泛使用且都不言自明,凡是目标实现支持三字母名称(MON、TUE、WED)的地方,都应优先使用名称。

分钟字段里的 */5 是每五分钟吗?

是的,一般形式是步长:*/n 表示在该字段范围内每隔 n 个取值。微妙之处在于步长从范围的起点开始计算,而不是从当前时刻开始,因此分钟字段里的 */7 会在第 0、7、14、21 分钟运行,这与“从你此刻看时间起每七分钟”并不相同。步长可以与范围组合,例如 10-50/10 表示第 10、20、30、40、50 分钟。

相关工具