Cron 表达式生成器

全球通用工具

cron 表达式由五个字段组成——分、时、月内日期、月、星期几——本页会像调度器那样把它读回来:每个字段选中了什么、任务下次什么时候运行、折算成每天或每周运行多少次。粘贴一整行 crontab 时只会读取其中的调度部分,因为第五个字段之后的内容是命令,不是时间。

crontab 行的五个字段——分 时 月内日期 月 星期几——或下面某种方言的六个字段。`@daily` 这类宏在前两种方言里可用。

同一个表达式对不同调度器含义不同,这就是 cron 的方言差异:`0 12 * * 1` 对 Linux 是星期一,对把星期日算作 1 的 Quartz 是星期日。这个设置决定面板报告哪一种方言的读法。

任意 IANA 时区名。默认是 UTC,这样运行时间不取决于页面在哪里打开;设成服务器所想的时区,就能看到任务真正触发的时间。

默认是今天的日期,这样页面 HTML 里的那份清单与这个标签页里的清单算的是同一串时刻。日期从当天 00:00 UTC 起算,这是把排期对照维护窗口检查的方式;想按此刻起算就填 `now`。

1 到 25。稀疏的排期回答起来更慢,因为搜索是按天走日历的。

留空则文件名为 “cron-schedule.txt”。

边输入边更新。所有计算都在你的浏览器里完成,数据不会离开本机。

按 5 字段方言读取

在 09:00,周一至周五

周三 2026-11-11 09:00(UTC+00:00)是下一次运行,9 小时后。

触发频率
每个匹配日 1 次
每周
5
下次运行
9 小时后
读取字段数
5

接下来 5 次运行(UTC 时区)

#  UTC 墙上时间           偏移       UTC                   距现在
-  ---------------------  ---------  --------------------  -------------
1  周三 2026-11-11 09:00  UTC+00:00  2026-11-11T09:00:00Z  9 小时后
2  周四 2026-11-12 09:00  UTC+00:00  2026-11-12T09:00:00Z  1 天 9 小时后
3  周五 2026-11-13 09:00  UTC+00:00  2026-11-13T09:00:00Z  2 天 9 小时后
4  周一 2026-11-16 09:00  UTC+00:00  2026-11-16T09:00:00Z  5 天 9 小时后
5  周二 2026-11-17 09:00  UTC+00:00  2026-11-17T09:00:00Z  6 天 9 小时后

第一列是 UTC 的墙上时间;第三列是同一瞬间的绝对 UTC 写法。计数起点是 2026-11-11T00:00:00Z。

每个字段选中了什么

字段写法含义选中的数值
分钟0:0000
小时90909
月内日期*每天
月份*每月
星期几1-5周一至周五周一、周二、周三、周四、周五

最后一列是字段在展开范围、列表与步长之后真正选中的每个值——这就是 `*/15` 会变成 00、15、30、45,而不是一个只能凭信任接受的符号的原因。

这些数字没有说明的

  • 这种方言把星期日算作 0,也接受用 7 表示它,所以 1 是星期一。Quartz 把星期日算作 1,同一个表达式在那里会指向另一天。
  • 下面的每个时间都从 2026-11-11T00:00:00Z 起算,也就是「从什么时候开始计数」里那个日期的 00:00 UTC(默认是今天,直到你改掉它)。所以清单取决于那个日期,而不是页面被打开的那一刻:页面 HTML 里保存的那份副本与浏览器里的这一页列出的是同一串运行时间。
读取只发生在当前浏览器标签页里,只用日历和浏览器自带的时区数据,不碰其他东西。要确认真正的调度器会怎么做,唯一可靠的办法是把表达式放进真正运行它的调度器——本页能说明表达式在说什么,但不能说明你的服务器会怎么处理它。

之所以需要这样一台工具,是因为同一串字符对不同调度器含义不同。`0 12 * * 1` 在 Linux 眼里是星期一,在把星期日算作 1 的 Quartz 眼里却是星期日;第六个字段在一种方言里是**秒**,在另一种方言里是**年**;`?`、`L`、`W`、`#` 只有 Quartz 认;而日期字段开头的 `*` 会悄悄关掉“两个日期字段用『或』连接”的规则。这些点都在页面上被逐一点名,而不是留到生产环境里才发现。

关于这个工具

深夜、周五、每季度一次的上午九点:cron 表达式是排期被写下来的方式,而本页会像调度器那样把它读回来——五个字段各自选中什么、任务下次何时运行、折算成每天或每周多少次。

读取只发生在当前标签页里:表达式不会被发送到任何地方。这一点在 crontab 行里出现内部主机名、或出现你不想描述的任务时尤其重要。本页会明确说明采用哪种方言——五字段还是六字段、Vixie 还是 Quartz、秒在最前还是年在最后——并指出陷阱,而不是靠猜。

同一串字符对不同调度器含义不同:`0 12 * * 1` 对 Linux 是星期一,对 Quartz 是星期日。页面会打印字段实际选中的值,并拒绝不会绕回的范围。在生产环境里相信某个“下次运行时间”之前,先确认方言。

它是怎么工作的

五个字段,以及每个字段里能写什么

顺序是分、时、月内日期、月、星期几,每个字段只能取自己范围内的数字:0-59、0-23、1-31、1-12、0-7。字段里出现的其他东西只能属于四种形状。范围写成 `1-5` 或 `MON-FRI`,后一种在月和星期字段里只是给人看的名字,含义与数字完全相同。列表写成 `1,15,30`。步长用斜杠表示“每隔 n 个”:分钟字段里的 `*/15` 就是 0、15、30、45。

最容易误读的形状,是数字后面跟步长,而不是星号后面跟步长。`3/10` 不是“第 3 分钟,然后每隔十分钟”,而是“从 3 到该字段范围末尾,每隔 10 个”,所以它选中 3、13、23、33、43、53。页面上的字段表会打印字段实际选中的值,这是确认步长有没有按你的意图工作最快的方法。

范围不会绕回。分钟字段里的 `50-10` 会被拒绝,而不会被读成跨越午夜的一小时,因为不同实现对此含义并不一致——请写成两段:`50-59,0-10`。名字不区分大小写;在从零开始计数的方言里,星期日可以写 `0` 或 `7`,这是一点小小的便利,也是大量混乱的来源。

五字段还是六字段,以及为什么第六个字段危险

标准 cron 有五个字段。其他都是扩展,而扩展对“多出来的字段放在哪里”意见不一。本页读取三种形状。五字段形式是 Linux 或 macOS crontab 以及 GitHub Actions 排期使用的那种。`node-cron`、Go 的 `robfig/cron` 和 Spring 的 `@Scheduled` 采用的六字段形式把**秒放在最前面**。Java 调度器 Quartz 也把秒放在最前,但在末尾增加一个可选的**年**,所以 Quartz 表达式有六个或七个字段。

陷阱在于,一个六字段表达式可能在不止一种读法下都合法。`0 0 12 * * ?` 在 Quartz 里是“每天中午”,而要求秒在最前的读法会直接拒绝它,因为 `?` 不是数字——这是拒绝,而不是静默地给出不同答案,属于好结果。对于避开 Quartz 专有符号的表达式,差异则是静默的:`0 0 12 * * 1` 对 Quartz 是星期日中午,对所有把星期日算作 0 的读法则是星期一中午。

还有两种形状值得知道,尽管本页不读取它们。AWS EventBridge 和 CloudWatch 把**分钟放在最前、年放在最后**——`cron(0 12 * * ? *)`——所以同样的六个记号在那里可能表示完全不同的排期。Jenkins 会在 cron 看到表达式之前,用任务名的哈希替换 `H`;systemd 定时器使用 `OnCalendar`,那根本不是 cron 语法。这些都会在拒绝信息里被点名,而不是被误读成三种形状之一。

月内日期与星期几用“或”连接

这是能困住人很多年的陷阱。当**两个**日期字段都指定了具体日期时,Vixie cron 在**任一**匹配时就会运行,而不是要求两者同时匹配。`0 0 1 * 0` 不是“每月 1 日,且恰好是星期日”,而是“每月 1 日午夜,以及每个星期日午夜”。要表达“只在 1 日是星期日时运行”,必须把判断移进命令本身。

一个字段是否算“指定了日期”,取决于它是否以 `*` 开头。这就是 `*` 与 `0-6` 不能互换的原因,尽管两者都覆盖每一天:`0 0 * * 0-6` 每天运行且指定了星期,而 `0 0 * * *` 什么日期都没指定。Quartz 用另一种方式解决同样的歧义:两个日期字段里必须有一个写 `?`,它拒绝同时指定两者,并用“与”而不是“或”连接剩下的那个。

Quartz 还有另外几种日期语法。月内日期字段里的 `L` 是当月最后一天,`LW` 是当月最后一个工作日,`15W` 是最接近 15 日的工作日——它不会跨出当月,所以如果 1 日是星期六,`1W` 会在 3 日星期一运行。星期字段里 `6#3` 是第三个星期五,`6L` 是最后一个星期五。Vixie cron 没有这些,所以“每月最后一天”通常只能变成对 `date` 的 shell 判断。

运行时间、时区,以及每年两次不听话的小时

cron 表达式命名的是墙上时钟,而不是某个瞬间,所以它的运行时间只有在某个时区里才有意义。本页在你选择的时区里读取表达式,并同时打印两者:带偏移的墙上时钟(`Wed 2026-09-16 09:00`、`UTC+02:00`),以及同一瞬间的绝对 UTC 写法,也就是日志搜索想要的形式。显示的偏移是那个瞬间生效的偏移,而不是今天的偏移,所以夏季任务会显示夏季偏移。

夏令时是墙上时钟不再构成全序的地方。时钟前拨时,本该是 02:00-03:00 的那一小时根本不会发生,所以安排在 02:30 的任务那天没有 02:30。时钟回拨时,同一小时会发生两次,02:30 也会出现两次。真实实现对此处理并不一致,所以本页不猜:时区跳过的读数会被报告为“跳过”,重复的读数取第一次出现,也就是真实机器上的任务第一次会运行的时刻。

搜索按日历走,而不是按滴答的时钟走,所以像 2 月 29 日这样稀疏的排期也能被正确回答:它测试的是日期而不是分钟,并把找到的运行时间报告为 `2028-02-29`、`2032-02-29` 等等。它向前看三十年,停下时会说明,并且绝不会列出你所问时区里不存在的墙上时间。

示例

示例使用页面自带的默认输入,只改设置;下面的结果与你在页面上看到的完全一致。

每十五分钟

Cron 表达式: */15 * * * * · 谁来读取它: 5 字段——Linux、macOS、GitHub Actions(分 时 日 月 周) · 按哪个时区读墙上时钟: UTC

按 5 字段方言读取

每 15 分钟,每天

周三 2026-11-11 00:15(UTC+00:00)是下一次运行,15 分钟后。

触发频率: 每个匹配日 96 次 · 每周: 672 · 下次运行: 15 分钟后 · 读取字段数: 5

这里要读的是字段表:00、15、30、45 被打印为分钟字段实际选中的值,没有任何东西需要凭空相信。统计行显示匹配日运行 96 次,也就是 24 小时里每小时四次。

柏林工作日上午九点

Cron 表达式: 0 9 * * 1-5 · 谁来读取它: 5 字段——Linux、macOS、GitHub Actions(分 时 日 月 周) · 按哪个时区读墙上时钟: Europe/Berlin

按 5 字段方言读取

在 09:00,周一至周五

周三 2026-11-11 09:00(UTC+01:00)是下一次运行,8 小时后。

触发频率: 每个匹配日 1 次 · 每周: 5 · 下次运行: 8 小时后 · 读取字段数: 5

运行时间会跳过周六和周日,落到下一个周一;每一行都带上柏林在那一天实行的偏移——夏季 +02:00,冬季 +01:00。换成 UTC 后,同一个任务夏季早两小时、冬季早一小时运行,这正是日志搜索想要的形式。

同一个表达式由 Quartz 读取

Cron 表达式: 0 0 12 * * 1 · 谁来读取它: Quartz——Java 调度器,六字段或七字段(支持 ? L W # 与可选年) · 按哪个时区读墙上时钟: UTC

按 Quartz 方言读取

在 12:00,周日

周日 2026-11-15 12:00(UTC+00:00)是下一次运行,4 天 12 小时后。

触发频率: 每个匹配日 1 次 · 每周: 1 · 下次运行: 4 天 12 小时后 · 读取字段数: 6

这是星期日中午,不是星期一:Quartz 把星期日算作 1。把方言切回五字段读法的 `0 12 * * 1`,下次运行就会从即将到来的星期日移到即将到来的星期一——一个设置,差一天,而表达式本身没有任何提示。

当月最后一个工作日

Cron 表达式: 0 0 12 LW * ? · 谁来读取它: Quartz——Java 调度器,六字段或七字段(支持 ? L W # 与可选年) · 按哪个时区读墙上时钟: UTC

按 Quartz 方言读取

在 12:00,每月最后一个工作日

周一 2026-11-30 12:00(UTC+00:00)是下一次运行,19 天 12 小时后。

触发频率: 每个匹配日 1 次 · 每周: 取决于月份 · 下次运行: 19 天 12 小时后 · 读取字段数: 6

Quartz 专有语法:`LW` 是当月最后一个工作日,问号表示“不指定星期几”,Quartz 要求两个日期字段里有一个这样写。运行时间落在每个月的月末而不是固定日号,所以如果某月以星期六结束,结果就是它前面的星期五。

常见问题

cron 表达式到底在说什么?

五个字段,顺序是分、时、月内日期、月、星期几。`0 9 * * 1-5` 是“在第 9 小时的第 0 分钟,每个月的每一天,星期一到星期五”——工作日上午九点。`*` 表示该字段的每个值;`1-5` 这样的范围表示这些值;`1,15` 这样的列表表示两者;`*/15` 这样的步长表示每第 15 个值。按顺序读,大多数表达式说的就是它看起来的样子。

为什么月内日期不匹配,任务还是运行了?

因为当两个日期字段都指定了日期时,它们用“或”连接。`0 0 1 * 0` 会在每月 1 日运行,也会在每个星期日运行;它不会等到 1 日恰好是星期日。这是标准 cron 行为,不是服务器故障,也是这个格式里最常见的意外。要只在 1 日是星期日时运行,可以安排 1 日并在命令内部判断星期,或者改用 Quartz——它会拒绝这个表达式,逼你二选一。

星期日是 0 还是 1,为什么我的任务在错误的日子运行?

取决于调度器,这正是任务跑错日子的原因。标准 cron 把星期日算作 0,也接受用 7 表示它,所以 1 是星期一。Quartz 把星期日算作 1,所以 1 是星期日、2 是星期一。AWS EventBridge 像 Quartz 一样按 1-7 计数,星期日为 1。因此 `0 0 12 * * 1` 这样的表达式在 Quartz 里是星期日中午,在所有从零计数的读法里是星期一中午,而表达式本身没有任何警告。方言设置就是为此存在的,面板也总会说明它用了哪种读法。

Quartz 里 ? 和 * 有什么区别?

两者都表示“这里没有值”;当两个日期字段中有一个指定了日期时,Quartz 坚持另一个必须写 `?`:`0 0 12 15 * ?` 是每月 15 日,`0 0 12 ? * FRI` 是每个星期五。两个字段都写 `*` 会被 Quartz 拒绝,因为 Quartz 用“与”连接两者,而那种情况从未实现;不过本页的 Quartz 读取器在两边都是 `*` 时会照常接受,并按“每天”解释——这是一个已知的宽松处。反方向也同样重要:在没有 `?` 的调度器里——比如 Linux crontab——`?` 是语法错误,而不是 `*` 的同义词;本页把 `?` 放错位置时只会报字段数不符或“这是 Quartz 语法”,不会替你移动它。

怎么安排“每月最后一天”?

在 Quartz 里写 `L`:`0 0 12 L * ?` 是每月最后一天中午,`LW` 是当月最后一个工作日。Quartz 还有 `L-3`,即月末前三天;本页读取 `L` 和 `LW`,但会拒绝带偏移的写法——而且拒绝信息只会说“L 在月内日期字段里不是可识别的名字”,并不会解释偏移语法,这是已知的粗糙处。标准 cron 没有 `L`,通常的变通是安排 28-31 日,让命令自己判断明天是不是 1 日,或者在脚本里算出日期。安排 31 日并不等于“最后一天”:它就是 31 日,二月会被悄悄跳过。

时钟前拨那天,02:30 的任务会怎样?

取决于机器,这正是值得了解它的原因。当时区从 02:00 跳到 03:00,那天根本不存在 02:30:有些 cron 实现会在变更后不久运行一次,有些会当天跳过,细节还因发行版而异。秋季同一个墙上时钟会出现两次,任务可能运行一次,也可能运行两次。本页不站队——它把读数报告为跳过或重复,并显示下一个真正发生的瞬间,好让排期能与服务器实际行为对照。

我的平台用的是哪种 cron?

Linux 或 macOS 的 crontab 以及 GitHub Actions 使用五字段 Vixie 形式,星期日为 0,Vixie cron 没有 `L`、`W`、`#`。Quartz(Java)和 Jenkins 采用秒在前的六字段,支持 `?`,Quartz 还增加 `L`、`W`、`#` 和可选的年。`node-cron`、启用秒的 Go `robfig/cron` 和 Spring 的 `@Scheduled` 采用秒在前的六字段,但没有 Quartz 符号。AWS EventBridge 采用分钟在前、年在后的六字段。Jenkins 还会用任务名的哈希替换 `H`,systemd 定时器使用 `OnCalendar` 而不是 cron。请确认真正会运行任务的调度器:本页读取其中三种形状,并会点名它不读取的那些。宏还有一个边界:`@daily` 会先展开成五字段表达式,如果你选的是六字段或 Quartz 方言,展开后只有五个字段,本页会拒绝它。

本页会把我的表达式发送到别处吗?

不会。表达式由运行在你浏览器标签页里的固定规则读取,运行时间也在同一个标签页里按日历计算,页面背后没有接口——它唯一发出的请求就是获取页面本身。页面 HTML 里的那份副本是生成页面时渲染的结果,所以没有 JavaScript 的访客看到的是真实读数,并在旁边写明计数起点,而不是一个空结果框。这里输入的内容不会被记录、存储或发送,也不会被上传到任何服务器。注意:本工具的输入内容(表达式)可能会保留在网页地址中,分享链接前请注意隐私。

资料来源与统计口径

  • 字段写法遵循大多数 Linux 使用的五字段 cron(Vixie 风格),也能读六字段与 Quartz。
  • 不支持的写法(AWS、Jenkins 的 `H`、systemd)会被点名说明;永远不触发的表达式会被拒绝。
  • 时区取自浏览器内置的 IANA 数据库;页面不安排任务、不上传,输入也不会上传。

最近复核于 2026-09-16.

本页在您的浏览器本地运行,请保留原文件备份;不涉及财务建议。 阅读完整免责声明。