使用方法
- 不勾选 Quartz 模式即为 5 字段 Vixie cron(分 时 日 月 周);勾选后新增「秒」字段变成 6 字段,且「日」「周」必须有一个填
?。 - 按示例填字段:秒 0、分 30、时 8、日
*、月*、周 1-5,含义是工作日每天 08:30。 - 推算起点填「年-月-日 时:分」,默认 2026-10-04 12:00;想推算接下来真实触发,点「取当前时刻」。
- 按回车或点「生成表达式」,表达式框输出结果,下方同时推算最近 5 次触发时刻。
- 报错会指出具体字段与允许范围,例如周字段填 8 会提示 0~7 的上限。
- 点「复制表达式」拿去配置 crontab;对照表可复制(TSV)或导出 CSV 存档。
Cron表达式生成器能解决什么问题
手写 cron 表达式最容易在字段个数、取值范围和特殊符号上翻车:把 5 字段的式子贴进 Quartz 会整体错位一格,把 Quartz 的 ? 贴进 crontab 直接报错。Cron表达式生成器把六个输入框限定在各自合法区间里,再反向推算「按这条规则接下来 5 次会触发的时刻」,让你在写进 crontab 或 Spring 的 @Scheduled 之前就能看出式子的真实节奏。
它不负责让任务真的跑起来——那是调度器的事:解析成功不等于任务会执行,服务器上 crond 没启动、Spring 配置没热加载、时区不一致,表达式再对也不会触发。只想反查一条现成表达式的含义,用Cron表达式解析。
推算时刻还必须有个明确的起点才有意义:同一表达式从周日中午和从周三半夜出发,接下来 5 次完全不同。本页把「推算起点」做成显式输入而不是隐藏的「现在」,默认给一个固定的演示基准——这样示例可复算,换台机器、换个时间打开,结果都一模一样。
原理与变量说明
5 字段与 6 字段的歧义。Vixie cron(Linux crontab)固定 5 字段:分 时 日 月 周;Quartz(Java 生态)是 6 字段 秒 分 时 日 月 周,还可追加第 7 个年份字段。两者最阴险的差异是周字段编号:Vixie 里 0 与 7 都是周日、1 是周一;Quartz 里 1 是周日、7 是周六。本页两种模式分开校验,勾选 Quartz 后填 0 会直接被拒——复算验证过:Vixie 的 1-5 与 Quartz 的 MON-FRI 归一后同为周一到周五,但 Quartz 的数字 2-6 才等于 Vixie 的 1-5。
步长与特殊符号。*/n 表示从下界起每 n 个单位:分钟 */15 命中第 0、15、30、45 分,每小时 4 次、一天 96 次。* 表示每个合法值;? 是 Quartz 专用的「不指定」占位符,日与周必须有一个填它——Quartz 禁止两处同时指定,而 Vixie cron 恰恰相反:日与周同时受限时取并集(任一匹配即触发)。L(最后一天)、LW(最后一个工作日)、nW(离 n 号最近的工作日)、n#k(第 k 个周 n)与周字段 nL(最后一个周 n)都是 Quartz 扩展,Vixie cron 均不支持,本页在 5 字段模式遇到它们会逐个报错。标准 cron 没有年份字段,「每年 2 月 29 日」这类需求只能靠 0 0 29 2 * 在非闰年空过。
日与周的并集规则。Vixie cron 有一条著名规定:日与周两个字段都受限时取并集,任一匹配即触发。本页把 * 视为「不约束」:日字段写 * 时只看周字段,两边都写 * 时每天触发。所以 0 0 29 2 * 只受日字段约束,平年不触发;可要是把周日字段写成 0-6 这种显式全集,日与周同时受限就变成并集,表达式会退化成 2 月每天触发——写全集反而改写了语义。Quartz 没有这个坑,它要求日与周必须有一个是 ?,无歧义的等价写法是 0 0 0 29 2 ?。
触发时刻推算。本页从推算起点当分钟起逐分钟向前匹配(上限 366 天 × 1440 分,共 527040 个分钟点),日匹配遵循 Vixie 的并集规则,Quartz 模式按 ? 展开后再套秒字段取该分钟内最早命中的秒。搜索一整年凑不满 5 次会明说,例如 0 0 29 2 * 在平年就是不触发——这是表达式语义,不是解析失败。
完整示例(数值仅作演示)
默认字段(秒 0、分 30、时 8、日 *、月 *、周 1-5)生成 30 8 * * 1-5。以推算起点 2026-10-04 12:00(周日)起,最近 5 次触发是 10-05 至 10-09 每天的 08:30,与结果区直出的演示块逐行一致。
勾选 Quartz 模式后,日字段变 ?、周字段平移成 2-6,得到 0 30 8 ? * 2-6——周字段从 1-5 到 2-6 正是编号歧义的直接后果,两条式子触发的是同一批工作日,只是秒字段从「没有」变成「第 0 秒」。再看两个 Quartz 扩展:0 0 12 ? * 2#1 表示每月第 1 个周一 12:00,从同一起点推算是 10-05、11-02、12-07、次年 01-04、02-01;0 0 0 15W * ? 表示离 15 号最近的工作日,11 月的 15 号是周日,触发日顺延到 11-16 而不是提前到 11-13。
常见写法对照表
各字段范围:秒与分 0~59,时 0~23,日 1~31,月 1~12(可用 JAN~DEC),周 Vixie 0~7、Quartz 1~7(可用 SUN~SAT)。下表 16 行常见写法覆盖两种口径,默认展示 12 行,点「加载更多」展开其余 4 行。
| 表达式 | 口径 | 含义 |
|---|---|---|
| 30 8 * * 1-5 | 5 字段 | 周一至周五每天 08:30 |
| */15 * * * * | 5 字段 | 每 15 分钟(每小时第 0/15/30/45 分) |
| 0 0 * * * | 5 字段 | 每天 00:00 |
| 0 9 1 * * | 5 字段 | 每月 1 号 09:00 |
| 0 22 * * 1-5 | 5 字段 | 工作日 22:00 |
| 0 0 29 2 * | 5 字段 | 2 月 29 日 00:00(仅闰年触发) |
| 5 * * * * | 5 字段 | 每小时第 5 分钟 |
| 15 14 1 * * | 5 字段 | 每月 1 号 14:15 |
| 0 30 8 ? * MON-FRI | 6 字段 | 工作日 08:30:00 |
| 0 0 3 * * 1-5 | 6 字段 | 周日至周四 03:00:00(Quartz 的 1 是周日) |
| 0 0 12 ? * 2#1 | 6 字段 | 每月第 1 个周一 12:00:00 |
| 0 0 0 L * ? | 6 字段 | 每月最后一天 00:00:00 |
| 0 0 0 15W * ? | 6 字段 | 离 15 号最近的工作日 00:00:00 |
| 0 0 2 ? * SAT | 6 字段 | 每周六 02:00:00 |
| 0 0 0 1 1 * | 6 字段 | 每年 1 月 1 日 00:00:00 |
| 0 0/30 9-18 * * ? | 6 字段 | 每天 9 点到 18 点半每 30 分钟一次 |
结果边界与舍入
逐字段校验。每个字段的空值、越界、非法字母都有带字段名与范围的报错:分字段 60 会指出 0~59;Vixie 周字段 8 会指出 0~7;Quartz 周字段 0 会被拒(Quartz 从 1 起算);5-1 这类下界大于上界的范围会被拒绝;步长 */0 因除零无意义同样报错。Quartz 下日与周同时受限会指出必须有一个是 ?。
推算精度。5 字段口径没有秒字段,触发时刻精确到分钟;Quartz 有秒字段时,同一分钟内取满足秒字段的最早一秒,起点那一分钟只看不早于起点秒数的值。时钟取本机时区,中国大陆无夏令时,不存在跳时导致的触发漂移;服务器若设为 UTC,同一表达式触发的小时数会差 8。
能力边界。本页不做宏替代(crontab 的 @daily 等简写)、不读系统 crontab 文件、不连接任何调度器,也不支持 Quartz 的 L-3 这类相对月末偏移与第 7 个年份字段;「会触发的时刻」是表达式语义的推演,crond 重载配置(systemd 下通常 systemctl reload crond)与应用侧调度器注册是另外的事。
常见问题
为什么我的表达式贴进 Quartz 就错位?
Quartz 比 Vixie 多一个秒字段在最前面,5 字段式子直接贴入后所有字段后移一位。按本页生成时先勾选 Quartz 模式,让秒位补齐成 6 字段再复制。
周字段的 1 到底是周一还是周日?
看引擎:Vixie cron 里 1 是周一(0 和 7 都是周日),Quartz 里 1 是周日。写名称 MON 或用 1-5 前先确认引擎,这是 cron 族最常见的移植坑。
? 和 * 有什么区别?
* 是「每个值都匹配」,? 是「不指定」占位。Quartz 要求日与周必须有一个填 ?;Vixie cron 没有 ?,允许日与周同时受限并按并集触发。本页把 * 视为不约束:日字段写 * 时只看周字段,两边都写 * 时每天触发——这正是 0 0 29 2 * 只在闰年触发的原因。
表达式解析成功了,为什么任务没跑?
解析成功只说明语法对。任务要执行还需要:调度进程在跑、配置已重载、服务器时区与预期一致、任务没有被并发策略跳过。先用本页看推算时刻,再到服务器核对 crond 日志。
L、W、# 是标准 cron 的语法吗?
不是,它们是 Quartz 扩展:L 最后一天、LW 最后一个工作日、nW 离 n 号最近的工作日(15 号是周日时顺延到周一 16 号,不提前到周五)、周字段的 n#k 表示第 k 个周 n。贴进 Linux crontab 会按字段校验失败。
想设「每年 2 月 29 日」怎么办?
标准 cron 没有年份字段,0 0 29 2 * 在平年不会触发也不会报错;要么接受「只在闰年触发」,要么在应用层判断年份。Quartz 下可写 0 0 0 29 2 ?,语义相同。
服务器在中国,夏令时会影响触发时间吗?
中国大陆不实行夏令时,本机时间推算不会漂移。若服务器时区是 UTC 或其他有夏令时的区域,同一表达式触发的小时会随政策或季节变化,先确认 date 命令输出。
*/15 一天到底跑多少次?
分钟 */15 每小时命中第 0、15、30、45 分共 4 次,一天 96 次;它从 0 起算而不是从你写入的当前时刻起算,想要错峰请改起始值,如 7-59/15。
相关工具
- Cron表达式解析:拿现成表达式反查含义,与本页的生成方向互补。
- 正则表达式测试工具:另一类容易手滑的领域专用语言,可实时匹配验证。
- Robots.txt生成器:同样面向「按时刻/规则被机器读取」的配置生成。
- UTM链接生成器:给营销链接拼查询参数,同为多字段拼接式工具。
- HTTP状态码代码速查表:排查定时任务回调失败时常用。
- 环境变量转JSON转换器:部署定时任务时整理配置的另一环。
- Meta标签生成器:页面级元信息生成,字段式拼接思路相同。