工作原理
五个字段依次是分钟、小时、日、月、星期。每个字段都接受单个值、逗号分隔的列表、连字符表示的范围,以及斜杠表示的步长——因此分钟字段里的 */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