Cron 表达式生成器
可视化生成和解析 Cron 定时任务表达式
什么是 Cron 表达式?
Cron 表达式是一种用于配置定时任务的字符串格式,由 6 到 7 个字段组成,按顺序分别表示秒、分、时、日、月、周、年(可选)。它最早起源于 Unix 系统的 cron 守护进程,如今被广泛应用于各类任务调度框架,如 Quartz、Spring Schedule、Kubernetes CronJob 等。通过灵活组合各字段的值,可以实现从「每分钟执行」到「每年特定日期执行」等各种复杂的定时逻辑。
使用方法
使用方法
- 选择生成或解析模式
- 通过下拉框设置时间字段(秒、分、时、日、月、周几)
- 点击预设可快速填充常用表达式
- 生成模式显示表达式及接下来 5 次运行时间
- 解析模式验证已有表达式并显示运行时间
语法符号
- * — 所有可能的值
- , — 列出多个值(如 1,3,5)
- - — 范围(如 1-5)
- / — 步长间隔(如 */5 表示每 5 个单位)
- ? — 不指定具体值(用于日或周几字段)
- L — 月/周的最后一天
- W — 最近的工作日
- # — 第 N 个周几(如 2#3 表示第 3 个星期二)
开发提示
- 将结果作为快速参考,然后在实际代码、构建或 API 环境中进行测试。
- 注意版本差异、语法变体、环境变量和项目约定。
重要提示
- 日和周几字段不能同时有值,其中一个必须使用 ?
- 每个字段有有效范围:分 0-59,时 0-23
- 字段顺序固定:秒 分 时 日 月 周几 年
- 周几不区分大小写,MON 和 mon 效果相同
使用场景
技术原理
Cron 表达式按固定顺序在各字段中编码零个或多个时间匹配约束。经典的 Vixie/BSD cron(Linux crond 使用)有 5 个字段:分钟(0-59)、小时(0-23)、日(1-31)、月(1-12 或 JAN-DEC)、星期(0-6 或 SUN-SAT,按惯例周日 = 0)。Quartz 调度器(由 Spring 和 Egistix 库推广)在前面增加了秒字段变为 6 个字段,末尾还可以加可选的年字段变为 7 个字段。每个字段可以是字面值、列表(1,3,5)、范围(1-5)、步长(0/15 表示从 0 开始每隔 15)或通配符 *(匹配所有值)。问号 ? 是 Quartz 专有的哨兵值,表示「无特定值」,当另一个日期字段有约束时,必须在日或星期其中一个位置使用。 计算接下来 N 次执行时间采用贪心前向搜索算法:从参考时刻(通常是当前时间)开始,递增不匹配约束的最低级字段,将所有更低级字段重置为最小值,当字段溢出时向更高级字段级联(例如分钟超过 59、小时超过 23)。这就是 Donovan/Spoonhour 迭代方法,时间复杂度为 O(K x F),其中 K 是候选数量(通常为 5),F 是字段数。星期名称(MON、FRI 等)会被转为小写后匹配,月份名称缩写同样支持。Quartz 中的 L 特殊字符解析为月中某个星期几的最后一次出现(例如 0 0 0 ? * 5L 是最后一个周五),通过从月末倒数查找目标星期几来计算。W 字符查找给定日期最近的工作日(周一至周五),必要时会跨到相邻月份。 时区处理是最常见的配置错误:表达式本身不携带时区元数据,因此相同的 0 0 9 * * ? 在 America/New_York、Asia/Tokyo 和 UTC 的服务器上会在不同的 UTC 偏移量触发。简写如 @daily(0 0 0 * * ?)、@hourly(0 0 * * * ?)、@reboot(守护进程启动时运行一次,不是时间表达式)和 @weekly(0 0 0 ? * 1)在解析前会展开为等价的 6 字段形式。一个常见的陷阱是日和星期的组合逻辑:在经典 cron 中,两者任一匹配即执行(OR 逻辑),而一些较新的方言切换为 AND 逻辑。表达式 0 0 0 15 * 5 在 Vixie cron 中表示「在 15 号午夜 AND 在每个周五午夜」,而非许多初学者以为的「在 15 号或周五的午夜」。Y2038 问题不会直接影响 cron(它使用 time_t),但任何运行 32 位 Unix crond 的嵌入式设备将在 2038-01-19T03:14:07Z 时发生 time_t 有符号 32 位整数溢出。
- 经典 5 字段:分 时 日 月 周;Quartz 增加秒(6 字段)和可选的年(7 字段)。
- ? 必须在日/周其中一个字段有值时占据另一个位置;* 匹配该字段的所有值。
- 日 + 星期的组合逻辑:Vixie cron 是 OR,部分较新调度器是 AND — 部署前务必确认。
- L 解析为月中最后一个星期几:例如 0 0 0 ? * 5L = 最后一个周五,从月末倒数计算。
- W 查找给定日期最近的工作日(周一至周五);可能跨到相邻月份。
- Cron 表达式不携带时区元数据:同一表达式在不同服务器上按本地时间、UTC 或命名时区触发。
- Y2038:32 位 time_t 在 2038-01-19 03:14:07 UTC 溢出;旧嵌入式系统上的 crond 将受影响。
- 简写 @hourly/@daily/@midnight/@weekly/@monthly/@yearly/@reboot 展开为等价的 5 字段或 6 字段表达式。
- 步长 / 运算符从最左侧值开始计数:hour 字段的 2/3 在 2、5、8、11、14、17、20、23 时触发。
- 五次迭代贪心前向搜索,时间复杂度 O(KxF),从参考时刻计算接下来 N 次运行时间。
示例
每天午夜执行(每日备份)
表达式 : 0 0 * * *
含义 : 每天 00:00 执行
下次执行: 2026-06-11 00:00, 2026-06-12 00:00, 2026-06-13 00:00
使用场景: 数据库备份、每日报表生成每 15 分钟执行一次(健康检查)
表达式 : */15 * * * *
含义 : 每小时的第 0、15、30、45 分钟执行
下次执行: 14:00, 14:15, 14:30, 14:45, 15:00
使用场景: API 健康检查、队列轮询、同步任务工作日上午 9 点(工作时段提醒)
表达式 : 0 9 * * 1-5
含义 : 周一到周五 09:00 执行
下次执行: 周一 09:00, 周二 09:00, 周三 09:00, 周四 09:00, 周五 09:00
使用场景: 站会提醒、Slack 每日摘要推送每月 1 号 03:30 执行(月度账单)
表达式 : 30 3 1 * *
含义 : 每月 1 号 03:30 执行
下次执行: 7 月 1 日 03:30, 8 月 1 日 03:30, 9 月 1 日 03:30
使用场景: 月度账单生成、日志切割归档每周日午夜执行(每周清理)
表达式 : 0 0 * * 0
含义 : 每周日 00:00 执行(在 Linux cron 中 0 表示周日)
下次执行: 周日 00:00, 周日 00:00, 周日 00:00
使用场景: 周报邮件发送、缓存清理、模型重训Quartz 带秒——每 30 秒执行一次
表达式 : */30 * * * * ?
含义 : 每 30 秒执行一次(6 字段 Quartz 语法)
下次执行: 14:00:00, 14:00:30, 14:01:00, 14:01:30
注意 : 因为 day-of-month 是 *,所以 day-of-week 用 ?。这种写法要用 Quartz,不能用 Linux cron。常见问题
支持哪些 cron 格式?
支持标准 5 字段 cron(minute hour dayOfMonth month dayOfWeek)、带秒的 6 字段(被 Quartz、Spring 和许多云调度器使用),以及带可选年份的 7 字段。页面允许你选择具体格式,并在你编辑表达式时对每个字段做出说明。
为什么 dayOfMonth 和 dayOfWeek 是两个独立的字段?
标准 cron 把它们视为「或」的关系:「每月 1 号 OR 每周一」只要满足其中一个条件就会触发。要表达「与」的关系,通常需要非标准的 ?-语法(Quartz)或采用变通方式。页面会显示接下来的触发时间,方便你直观地确认设置是否符合预期。
这个调度真的会在我的系统上执行吗?
不会——本页只是生成并校验表达式,任务还是要由你自己的调度器(Linux cron、GitHub Actions、Kubernetes CronJob、AWS EventBridge、Quartz 等)来执行。不同调度器使用的 cron 方言略有不同,请按目标平台选择正确的格式。
调度使用的是哪个时区?
标准 Unix cron 使用系统本地时区。云调度器各不相同——AWS EventBridge 默认 UTC,GitHub Actions 默认 UTC,Kubernetes CronJob 使用 API Server 的时区。请阅读对应调度器的文档,并注意夏令时切换可能让任务在意想不到的时间触发。
如何表示「每 30 分钟一次」?
*/30 * * * *(minute = 0,30;每小时、每天、每月、每周任意一天)。「仅在工作时段每 15 分钟一次」可以写成 */15 9-17 * * 1-5(限定为周一至周五的 9:00-17:00)。页面会列出未来 5-10 次触发时间方便你确认。
可以放心地用于真实的生产调度吗?
页面只生成表达式,任务执行是你自己调度器的事。建议先用一次试运行验证表达式(多数调度器都有「手动执行」选项),并尽量避免把任务安排在午夜(00:00),因为大量系统的任务会在那个时间点撞车,造成集中负载。
有任何数据会被上传吗?
不会。表达式的解析以及未来触发时间的计算都通过一个 JavaScript cron 库在你的浏览器中完成。