Quartz Cron、Spring Cron、Linux Crontab 区别和联系

定时任务领域常见的三种 cron 写法:Quartz Cron(Java 调度框架)、Spring Cron(Spring @Scheduled)、Linux Crontab(系统级定时任务)。三者名称相近、格式相似,但字段数量、星期取值、特殊符号和「日 / 周」规则并不完全相同。混用时最容易写错表达式,本文从联系与差异两方面对照说明。

一、三者的联系

  •     1.  都使用空格分隔的多段式字符串描述「何时执行」,核心思想一致:在指定时间点或周期触发任务。
  •     2.  都支持基础符号 *(任意)、,(枚举)、-(范围)、/(步长)。
  •     3.  Spring Cron 语法继承自 Quartz,6 段字段顺序与 Quartz 前 6 段一致,扩展符号(?LW#)也基本相同。
  •     4.  Quartz 与 Spring 的「日 / 周」采用互斥规则(其中一个须为 ?);Linux crontab 则为或(OR)关系。
  •     5.  许多「每天 / 每小时 / 每 15 分钟」的业务语义,三种写法都能表达,只是字符串不同,不能直接复制粘贴。

二、字段结构与格式

2.1 字段结构对照

类型 段数 字段顺序 典型使用场景
Quartz Cron 6~7 段 秒 分 时 日 月 周 [年] Quartz Scheduler、部分分布式任务框架
Spring Cron 6 段 秒 分 时 日 月 周 Spring / Spring Boot @Scheduled(cron="...")
Linux Crontab 5 段 分 时 日 月 周 crontab -e、系统 cron、Ansible 等

2.2 格式示意图

Quartz Cron(6~7 段)

*   *   *   *   *   *   *
-   -   -   -   -   -   -
|   |   |   |   |   |   +-- 年(可选)
|   |   |   |   |   +------ 周
|   |   |   |   +---------- 月
|   |   |   +-------------- 日
|   |   +------------------ 时
|   +---------------------- 分
+-------------------------- 秒

Spring Cron(6 段,无「年」)

*   *   *   *   *   *
-   -   -   -   -   -
|   |   |   |   |   +------ 周
|   |   |   |   +---------- 月
|   |   |   +-------------- 日
|   |   +------------------ 时
|   +---------------------- 分
+-------------------------- 秒

Linux Crontab(5 段,无「秒」、无「年」)

*   *   *   *   *
-   -   -   -   -
|   |   |   |   +------ 周
|   |   |   +---------- 月
|   |   +-------------- 日
|   +------------------ 时
+---------------------- 分

三、核心差异

3.1 核心差异一览

对比项 Quartz Cron Spring Cron Linux Crontab
是否有「秒」
是否有「年」 可选第 7 段
星期取值 1~7 或 SUN~SAT(1=周日) 0~7 或 SUN~SAT(0 与 7=周日) 0~7 或 SUN~SAT(0 与 7=周日)
支持 ? 是(日 / 周) 是(日 / 周)
支持 L W # 是(L/W/# 需 Spring 5.3+)
「日」与「周」关系 互斥,须有一个为 ? 互斥,须有一个为 ? 独立;同时指定时为 OR(满足其一即执行)
最小粒度 秒级 秒级 分钟级

3.2 同一语义,三种写法

以下表达「同一业务含义」时,字符串不能通用,须分别编写:

业务含义 Quartz / Spring(6 段) Linux Crontab(5 段)
每分钟 0 * * * * ? * * * * *
每小时整点 0 0 * * * ? 0 * * * *
每天凌晨 0 0 0 * * ? 0 0 * * *
每天上午 9 点 0 0 9 * * ? 0 9 * * *
工作日 9 点 0 0 9 ? * MON-FRI 0 9 * * 1-5
每 15 分钟 0 0/15 * * * ? */15 * * * *
每月 1 号凌晨 0 0 0 1 * ? 0 0 1 * *

说明:上表 Quartz 列与 Spring 列在以上示例中写法相同;Spring 不支持第 7 段「年」,其余 6 段与 Quartz 一致。Linux 列因缺少「秒」段,整体字段会少一段且顺序不同

四、星期字段对照

4.1 星期取值对照表

类型 周日 周一 周二 周三 周四 周五 周六 备注
Quartz Cron 1 或 SUN 2 或 MON 3 或 TUE 4 或 WED 5 或 THU 6 或 FRI 7 或 SAT 1=周日,7=周六
Spring Cron 0 或 7 或 SUN 1 或 MON 2 或 TUE 3 或 WED 4 或 THU 5 或 FRI 6 或 SAT 0 与 7 均为周日
Linux Crontab 0 或 7 或 SUN 1 或 MON 2 或 TUE 3 或 WED 4 或 THU 5 或 FRI 6 或 SAT 0 与 7 均为周日;支持 SUN~SAT

4.2 写法示例

示例:「每周一 9 点」
Quartz / Spring:0 0 9 ? * MON0 0 9 ? * 2(Quartz 中 2=周一)
Spring 也可写:0 0 9 ? * 1(1=周一)
Linux Crontab:0 9 * * 1(1=周一)或 0 9 * * MON(英文缩写)

五、「日 / 周」规则差异

5.1 Quartz / Spring:互斥

「日」与「周」不能同时指定具体值,其中一个必须为 ?

正确:0 0 0 15 * ?(每月 15 号)
正确:0 0 0 ? * MON(每周一)
避免:0 0 0 15 * MON(日、周同时指定)

5.2 Linux Crontab:或(OR)关系

「日」与「周」可以同时有值,满足任一条件即执行。

0 0 2 * 1
日字段 *:每天;周字段 1:每周一
结果:每天凌晨 2 点每周一凌晨 2 点都会触发(因「每天」已包含周一)

0 0 2 2 1
日字段 2:每月 2 号;周字段 1:每周一
结果:每月 2 号每周一凌晨 2 点执行

最佳实践:Linux 中按「星期几」调度时,日期字段用 *;按「几号」调度时,星期字段用 *

六、特殊字符支持对照

字符 含义 Quartz Spring Linux
* 任意值
, 枚举
- 范围
/ 步长
? 不指定(日 / 周)
L 最后(日 / 周) ✓(5.3+)
W 最近工作日 ✓(5.3+)
# 第 N 个星期 X ✓(5.3+)

七、选型与互转

7.1 如何选型

场景 推荐
Spring Boot 应用内定时任务 Spring Cron(@Scheduled
Quartz 集群、持久化、复杂调度 Quartz Cron(可含「年」段)
Linux 服务器脚本、系统运维 Linux Crontab(5 段)
需要秒级触发 Quartz / Spring(Linux 最小到分钟)
需要「每月最后一个周五」等高级规则 Quartz / Spring(L#);Linux 不支持

7.2 互转注意

  •     1.  Quartz → Spring:去掉第 7 段「年」即可;6 段部分通常可直接使用。
  •     2.  Spring → Quartz:6 段可直接用于 Quartz;需要按年过滤时再加第 7 段。
  •     3.  Quartz/Spring → Linux:去掉「秒」段;检查「日 / 周」是否用了 ?(Linux 不支持,需改为 * 或具体值);核对星期数字含义。
  •     4.  Linux → Quartz/Spring:在最前面补「秒」段(常为 0);「日 / 周」若原为 OR 关系,需改为互斥并加 ?
  •     5.  含 LW# 的表达式无法直接用于 Linux crontab。

八、相关工具与教程

类型 在线生成器 详细教程
Quartz Cron Cron 生成器 Cron 教程
Spring Cron Spring Cron 生成器 Spring Cron 教程
Linux Crontab Crontab 生成器 Crontab 教程