Crontab Guru

五个字段,以空格分隔;也可以使用 @daily 这类简写。

粘贴一个 cron 表达式,即可用你自己的语言逐字段了解它到底在做什么。无需记住字段顺序,也不用去查取值范围:Guru 会逐一讲解五个字段(分钟、小时、日期、月份和星期),并从左到右解读整个表达式。适合在部署前检查 crontab 中的某一行,或解释一段接手过来的配置。

如何使用 Guru

  1. 1

    粘贴表达式

    把任意标准的 5 字段 cron 表达式(例如 `0 9 * * 1-5`)复制到输入框中。

  2. 2

    阅读拆解结果

    工具会先用一句话说明这个计划的执行时间,然后拆解全部五个字段:分钟、小时、日期、月份和星期。月份和星期的数字会以名称显示。

  3. 3

    查看接下来的运行时间

    最后一步会列出该任务接下来的五次运行时间,并按你所在的时区计算,而不是服务器的时区。当计划的实际执行范围比字面看上去更广,或者日历上根本没有任何日期与之匹配时,工具也会给出提醒。

  4. 4

    部署前先核对

    在把它写进 crontab、CI 配置或 Kubernetes 清单之前,先用这段说明确认调度行为符合你的预期。

字段速查表

 ┌───────────── 分钟 (0-59)
 │ ┌─────────── 小时 (0-23)
 │ │ ┌───────── 日(一个月中的第几天,1-31)
 │ │ │ ┌─────── 月 (1-12 或 JAN-DEC)
 │ │ │ │ ┌───── 星期几 (0-6 或 SUN-SAT;周日 = 0 或 7)
 │ │ │ │ │
 * * * * *

cron 表达式中的运算符

运算符 含义 示例
* 所有值 * * * * *
, 值列表 0,15,30,45
- 范围 9-17
/ 步长(起始值/步长) */5、0-30/5
L 最后(当月最后一天,或最后一个匹配的星期几,Quartz) L、5L
W 最近的工作日 15W(Quartz)
# 当月第 N 个匹配的星期几 1#3(Quartz)
? 不指定具体值 仅 Quartz 支持

阅读顺序很重要

0 */2 * * 1-5 从左到右读作:第 0 分钟、每 2 小时、任意日、任意月、周一到周五。人们有时会出于习惯从右往左读这些字段而被搞糊涂;一定要从“分钟“开始读。

“每 X 分钟”的陷阱

*/10 * * * * 会在第 0、10、20、30、40、50 分钟执行,而不是“从任务创建那一刻起每 10 分钟一次“。cron 的步长始终从该字段取值范围的起点开始计算。如果你在 12:03 部署任务,首次运行会在 12:10,而不是 12:13。

对于确实需要“距上次运行 N 分钟后“执行的任务,请使用带持久计时器的调度器(使用 OnUnitActiveSec 的 systemd 定时器,或在应用层调度并保存上次运行的时间戳)。

值得了解的 cron 陷阱

  • 同时设置了“日“和“星期几“:大多数 cron 实现会按“或“逻辑处理,多半不是你想要的结果。
  • 步长为 0:*/0 无效。
  • 范围跨过午夜:表示小时的 22-2 在传统 cron 中不起作用;请使用 22-23,0-2。
  • 2 月 30 日:像 0 0 30 2 * 这样的计划永远不会执行。
  • 夏令时(DST)的歧义:安排在凌晨 2 点到 3 点之间的任务,在夏令时切换日可能会执行两次,也可能一次都不执行。

cron 与现代调度器的对比

Unix 的 cron 至今仍随处可见,但对于关键任务,你大概会需要下面这些:

  • systemd 定时器:能补上漏掉的运行、支持随机偏移、从 unit 文件读取配置。
  • Kubernetes CronJob:声明式,支持重试,并在 1.25 及以上版本支持时区。
  • Airflow / Prefect / Dagster:适用于存在依赖关系、重试、回填和可观测性需求的任务。
  • GitHub Actions 定时计划:5 字段 cron,仅支持 UTC,最小间隔 5 分钟,尽力而为(best-effort)地交付。

cron 本身是一种很好的格式,但对于绝不能错过的任务来说,它是个糟糕的调度器。

常见问题

因为在标准 cron 中,星期几的 0 表示周日(7 也表示周日,因此两种约定都支持),周一是 1。而 Quartz 把星期几编号为 1 到 7,并把周日记作 1,这常常让在不同实现之间切换的人栽跟头。

传统的 Unix cron 运行在服务器的本地时区,也就是 /etc/timezone 所指定的时区。Kubernetes 的 CronJob、GitHub Actions 以及大多数云端调度器默认都使用 UTC。请务必确认,并尽量使用 UTC,以避免夏令时带来的意外。

传统 cron 无法直接表达这一点。变通做法是:每周一都运行,并在脚本里检查日期:[ $(date +%d) -le 7 ] && ./job.sh。Quartz 则用 1#1 原生支持。

不能。每个计划都需要单独占一行。不过你可以用列表把多个时间点合并到一行:0 9,17 * * * 会在上午 9 点和下午 5 点运行。对于无法用一行表达的计划,请添加多行,指向同一条命令。

相关工具

此工具还提供其他语言版本