Cron 表达式生成器,免费
以可视化方式构建和理解 cron 任务计划。
快速预设
接下来 5 次运行
Cron 语法参考
* · 任意值
*/5 · 每 5 个单位
1,15 · 在 1 和 15
1-5 · 从 1 到 5 范围
字段:分钟(0–59)、小时(0–23)、日(1–31)、月(1–12)、星期(0–6,0 = 周日)
cron 表达式的简史
五字段 cron 表达式可追溯至 1975 年 5 月,当时一个早期版本作为 Research Unix 第 7 版的一部分从 AT&T Bell 实验室发布。该名称暗示 Chronos,希腊时间的拟人化。格式很简单:在 /usr/lib/crontab 中一行上五个空格分隔字段(分钟、小时、月中日、月、星期)。Paul Vixie 于 1987 年的 Vixie cron 重写成为事实上的现代实现;每个主要的 Linux 发行版都附带 Vixie 派生的 cron,Vixie 添加了每个用户的 crontab、环境变量支持(MAILTO=、CRON_TZ=)和大家今天使用的 @hourly / @daily / @reboot 快捷宏。然后 cron 表达式语法沿着两条路径分叉。Quartz Scheduler(Java,James House,1998;捐赠给 Apache 和 Terracotta)添加了前导秒字段、可选的尾随年字段和 L(last)/W(weekday)/#(第 n 次出现)运算符,产生了六字段 cron,AWS EventBridge(最初是 CloudWatch Events,2014)和 Spring 的 @Scheduled 注释后来采用了它。Azure Functions(2016)使用的 NCronTab 格式将秒放在首位但保留了五个行为字段。云时代然后将五字段 Vixie 格式标准化为通用语言:Kubernetes CronJobs(2016 年 1.4 版的 alpha,2021 年 1.21 版的 GA)接受恰好五个字段,GitHub Actions(on.schedule.cron,2019)、GCP Cloud Scheduler(2018)和 Vercel Cron Jobs(2022)也是如此。可视化 cron 构建器,本工具所属的类别,大约在 2010-2015 年间出现:crontab.guru(Christine Dodrill,2014)成为引用最多的参考,而 cron-descriptor 库(Brady Holt,最初是 .NET,移植到 Java/Python/JS)驱动了大多数解码器和生成器所依赖的「cron 用简单英语」翻译层。Bell 实验室半个世纪之后,同样的五个字段仍在调度世界的夜间备份。
cron 表达式的结构
- 五个字段,由空格分隔。按顺序:
分钟 (0-59) 小时 (0-23) 月中日 (1-31) 月 (1-12) 星期 (0-6)。表达式0 9 * * 1表示「分钟 0、小时 9、任何月中日、任何月、星期 1(周一)」,即每周一上午 9:00。月份从 1 开始;0 0 1 0 *无效,因为没有月份 0。 - 四个运算符。
*匹配字段范围内的所有值。,列出离散值:分钟字段中的0,15,30,45。-定义范围:小时字段中的9-17涵盖上午 9 点到下午 5 点。/设置步长:分钟中的*/15在 0、15、30、45 触发。这四个运算符可以自由组合:*/15 8-18 * * 1-5表示「每 15 分钟在 8 到 18 之间,仅工作日」。 - 快捷宏。Vixie cron 和大多数现代解析器接受
@yearly(或@annually,等同于0 0 1 1 *)、@monthly(0 0 1 * *)、@weekly(0 0 * * 0)、@daily(或@midnight,0 0 * * *)、@hourly(0 * * * *)和特殊的@reboot(当 cron 守护进程启动时运行一次)。云平台不同:GitHub Actions 和 Vercel 拒绝这些宏。 - 步长陷阱。范围为 a-b 的字段中的
*/N在 a、a+N、a+2N、... 触发,不一定是壁钟时间的每 N 个单位。分钟字段中的*/7在 0、7、14、21、28、35、42、49、56 触发,然后在下一小时的开始跳回 0,产生 4 分钟的差距。在没有包装器的标准 cron 中,真正的每 7 分钟调度是不可能的。 - OR 陷阱(月中日 vs 星期)。当两个字段都受限时,标准 Unix cron 在任一匹配时触发,而不是两者都。
0 0 1 * 1不意味着「在 1 号的周一」,意味着「每月 1 号,加上每个周一」。crontab(5)手册页是明确的。Quartz、AWS EventBridge 和 systemd 计时器都能干净地表达「第一个周一」;Vixie cron 需要包装器。 - 星期编号各异。Linux/Vixie、GitHub Actions、GCP Cloud Scheduler、Kubernetes、Azure NCronTab 和 Spring 5.3+ 都使用星期日 = 0(Vixie 也接受 7)。Quartz 和 AWS EventBridge 使用星期日 = 1。因此
0 0 * * 1在 Linux 上意味着「每周一」但在 Quartz 下意味着「每周日」。当可移植性重要时,使用三字母名称(MON、TUE)。
表达式在哪里使用
- Linux / macOS cron。粘贴到
crontab -e后跟命令。接受名称(MON、JAN)和快捷宏(@hourly、@daily、@reboot)。如果服务器在 UTC 但你想按本地时间调度,在 crontab 顶部设置CRON_TZ=America/New_York。 - Kubernetes CronJob。将
spec.schedule设置为你的五字段表达式。spec.timeZone(1.27 GA,2023 年 3 月)接受 IANA 区域如「Europe/Paris」。从 1.29 起,在调度字符串中嵌入TZ=被拒绝。使用spec.startingDeadlineSeconds控制停机后的追赶行为。 - GitHub Actions。放入
on.schedule.cron。调度在 UTC 中运行,最短节奏是 5 分钟(任何更精细的都会被静默舍入),公开仓库中的计划工作流在仓库不活动 60 天后自动禁用。YAML 中的 cron 字符串必须用引号引起来,以避免解析器与前导*的混淆。 - AWS EventBridge / EventBridge Scheduler。使用六个字段:
cron(min hr dom mon dow yr)。要求?在月中日或星期之一(不是两个文字)。Quartz 风格的L(最后)、W(工作日)和#(第 n 次出现)运算符在这里都有效。Scheduler 产品(2022)添加了单独的at()表达式用于一次性定时器。 - GCP Cloud Scheduler。匹配 Linux 的五字段语法。
timeZone属性接受 IANA 区域。与 Cloud Pub/Sub 或 HTTP 目标组合。retryConfig处理瞬态故障;默认为不重试,这让期望至少一次语义的工程师感到惊讶。 - Vercel Cron Jobs。
vercel.json中的五字段语法。两个日字段不能同时设置。Hobby 计划将节奏限制为每日;Pro 计划允许每小时。触发 HTTP GET 到你的函数路径,这意味着如果触发器重试,函数必须是幂等的。
标准、方言和里程碑
- AT&T Bell 实验室 cron(1975 年 5 月)。原版。五个字段,没有每个用户的 crontab,从
/usr/lib/crontab运行。Research Unix 第 7 版的一部分。所有现代变体都扩展的空格分隔语法。 - Vixie cron(Paul Vixie,1987)。大家运行的重写。添加了每用户 crontabs、
@hourly/@daily/@reboot宏、名称别名(MON、JAN)和MAILTO/CRON_TZ环境变量。大多数 Linux 发行版附带 Vixie cron、dcron 或 cronie(Vixie 的 Red Hat 分支)。 - Quartz Scheduler(James House,1998)。引入六字段 cron(带前导秒)和
L/W/#运算符的 Java 库。捐赠给 Apache 然后 Terracotta。Spring 的@Scheduled注释嵌入了 Quartz 语义;Spring 5.3+ 有争议地将星期从 Quartz 的「星期日=1」切换到 Linux 的「星期日=0」,所以同一个字符串现在在不同版本下意味着不同的日子。 - systemd 定时器(Lennart Poettering,2010)。在大多数现代 Linux 发行版上取代 cron。使用不同的语法(
OnCalendar=Mon..Fri 09:00),支持日历和单调调度,记录到journald,可以声明服务依赖项,用systemd-analyze calendar验证,并通过Persistent=true结合 cron 式精度与 anacron 式追赶。 - NCronTab(Azure Functions,2016)。六个字段,秒在首位:
{second} {minute} {hour} {day} {month} {day-of-week}。没有年字段。默认时区是 UTC;在 Linux App Service 计划上用WEBSITE_TIME_ZONE应用设置覆盖。 - AWS EventBridge cron 语法。六个字段,年在最后:
cron(min hr dom mon dow yr)。在未使用的 dom/dow 之一中需要字面?作为占位符。支持 QuartzL、W、#。最初是 CloudWatch Events(2014),2019 年更名为 EventBridge。 - 5-vs-6 字段可移植性问题。将五字段 Linux 表达式粘贴到 Quartz 或 Spring 会产生「cron expression must consist of 6 fields」错误;将六字段表达式粘贴到 Linux cron 会产生「bad day-of-week」,因为 Linux 将秒列读作分钟。相反的错误更危险,因为它可以静默解析并在错误的调度上运行。
- Jenkins
H(哈希)扩展。Jenkins 用H扩展标准 cron,它为每个作业选择稳定但随机的值,而不是在同一瞬间运行每个作业。H * * * *意味着「每小时,但每个作业在不同的分钟」,防止许多作业在第 0 分钟调度时的「雷鸣群」问题。
更多常见问题
五个字段与六个或七个字段相同吗?
不。经典的 POSIX 形式是五个字段(分钟、小时、月中日、月、星期)。Quartz 和 Spring 通过添加前导秒列使用六个字段,Quartz 接受可选的第七年字段。AWS EventBridge 总是使用以年结尾的六个字段(cron(min hr dom mon dow yr))。将五字段表达式粘贴到 Quartz 或 Spring 会引发语法错误;将六字段表达式粘贴到 Linux 会静默地误解字段。
cron 可以表达的最小间隔是多少?
标准 Unix cron 上每分钟(* * * * *)。没有内置秒字段。如果你需要亚分钟节奏,Quartz 或 NCronTab 之类的调度器会添加一个,systemd 定时器可以使用 OnUnitActiveSec=30s。GitHub Actions 将最短节奏限制为 5 分钟,EventBridge 在计划时间的 60 秒窗口内触发,所以不要依赖 cron 来获得硬实时精度。
如何在每月的最后一天运行作业?
标准五字段 cron 没有原生的「月份最后一天」运算符。Quartz 和 AWS EventBridge 在月中日字段支持 L:0 0 L * ? 在最后一天的午夜触发。在普通 Linux cron 上,通常的解决方法是在候选日上每天调度并门控命令:0 0 28-31 * * [ "$(date +\%d -d tomorrow)" = "01" ] && /path/to/script。systemd 定时器直接用 OnCalendar=*-*-* 00:00:00 表达它。
为什么我的 cron 作业没有在我预期的时候运行?
通常的嫌疑人,按顺序:(1) 服务器与你假设的时区不同(用 date 检查);(2) PATH 不是你的交互式 shell 所拥有的,所以一个命令在提示符下工作但在 cron 下失败(使用绝对路径);(3) 输出发送到电子邮件而你错过了(设置 MAILTO="" 或重定向到日志文件);(4) cron 守护进程未运行(systemctl status cron);(5) OR 陷阱(见上文)在你未打算的额外日子上触发。
cron、anacron 和 systemd 定时器之间有什么区别?
Cron 期望系统在计划时间运行并静默跳过停机期间的作业:对始终开启的服务器很好,对笔记本电脑不好。Anacron 按作业跟踪上次运行的时间戳,并在重启后追赶错过的作业,代价是日级而非分钟级精度。systemd 定时器在大多数现代 Linux 发行版上取代 cron:它们支持日历和单调调度,记录到 journald,可以声明服务依赖项,并使用 Persistent=true 结合 cron 式精度与 anacron 式追赶。
时区和夏令时如何影响 cron?
大多数 cron 守护进程在系统时区中解释调度。在云服务器上,这通常意味着 UTC,所以 0 9 * * * 在 9 AM UTC 触发,而不是本地 9 AM。在 Linux crontab 中设置 CRON_TZ=America/New_York;Kubernetes 使用 spec.timeZone;AWS、GCP 和 Vercel 各自采用显式 IANA 区域。在春季向前调整时,计划在跳过小时的作业由 Vixie cron 立即运行,但由 AWS EventBridge 完全跳过。最安全的模式是将 cron 留在 UTC 中,并在作业内转换。