前言

通过 cron 表达式 可以让计算机在 固定的时间点 特定时间间隔 下执行指定任务。时间间隔的单位可以是秒 *、分钟、小时、日、月、周、年的 任意组合 。非常适合周期性的日志、数据分析或数据备份等运维或管理工作。cron 该词来源于希腊语 chronos(χρόνος),原意是时间。
注意:crontab 最小单位是分钟,Quartz 最小时间单位是秒。

语法规则

cron 表达式 是一个字符串,该字符串分为 7,相邻的两个域由一个space 隔开。最后一个 (年)可省略 ,实际应用中多为前 6 个

1
2
{ 秒 } { 分 } { 时 } { 日 } { 月 } { 周 } { 年 }
{Seconds} {Minutes} {Hours} {DayofMonth} {Month} {DayofWeek} {Year}

注意:当「周」域为「*」时,容易错误理解为每周,但周是时间段而不是时间点,显然理解有误。实际上应理解作当前周的每一天,即「每天」。其实结合其英文原文「DayofWeek」还是很好理解的。这里我找不到更合适和贴切的翻译,就仍译作「周」。

各域规则

是否必填 取值范围 通配符
0-59 , - * /
0-59 , - * /
0-23 , - * /
1-31 , - * / ? L W C
1-12 或 JAN-DEC , - * /
1-7 或 SUN-SAT , - * / ? L C #
1970-2099 , - * /

特殊的表达式

特殊表达式 含义 等价一般表达式
@reboot 启动时触发一次
@yearly 每年运行一次 0 0 0 1 1 ? *
@annually (同 @yearly) (同上)
@monthly 每月触发一次 0 0 0 1 * *
@weekly 每周触发一次 0 0 0 * * 1
@daily 每日触发一次 0 0 0 * * ?
@midnight (同 @daily) (同上)
@hourly 每小时触发一次 0 0 * * * ?

域的通配符

通配符表达一些特殊含义,下列各通配符的中文释义是按照我理解及参考文献后个人定义的。
注意:cron 表达式对字母大小写不敏感。

  • , 逗号,表 列表值,类比数组的各元素,是并列关系。

    • 0 0 0 9,15 * ?
      (每月的)9 号和 15 号的 00:00:00 各触发一次。

    • 0 0,15,30,45 * * * ?
      (每月的每天的)每小时的 0 分、15 分、30 分、45 分(的 0 秒)各触发一次,即每 15 分钟触发一次。

  • - 中划线,表 连续区间值,指定区间内所有可能的值均可触发。

    • 0 0 9-13 * * ?
      (每月的)每天的 09:00-13:00 期间,每小时(的 0 分 0 秒)触发一次。等价于0 0 9,10,11,12,13 * * ?

    • 0 15 10 ? * 6L 2011-2014
      Fire at 10:15 a.m. on every last Friday of every month during the years 2011, 20012, 2014, and 2014

  • * 星号,表 任意值,取值范围内任意可能的值。

    • * * * * * ?
      (每月的每天的每小时的每分的)每秒触发一次。

    • 0 0 0 * * ?
      (每月的)每天的 00:00:00 触发一次。

  • / 斜杠,表 周期值,根据指定起始时间点和周期,间歇性触发。

    • 0 0 */6 * * ?
      从 00:00:00 开始,每 6 小时触发一次。等价于0 0 0,6,12,18 * * ?

    • 11/10 * * * * ?
      (每月的每天的每小时内,)从每分钟的第 11 秒开始,每 10 秒触发一次。等价于11,21,31,41,51 * * * * ?

  • ? 问号,表 未指定的值,即不关心它为何值。如果「日」或「周」域都指定数值容易冲突,即使不冲突也会重复指定,故常仅指定其一(都指定时以范围更精确的为准)。

    • 0 0 13 * * ?
      (每月的)每天的 13:00:00 触发一次。

    • 0 0 13 ? * *
      (每月的)每天的 13:00:00 触发一次。

  • L 字母 L(Last),表 最后一个值 ,只能在「日」和「周」域中使用。在「日」域中时,表 当月的最后一天 ;在「周」域中时,表 当周最后一天 (周六),等同于7SAT;若在「L」前加指定数字,则表示 最后一个指定日 ,如在「周」域设置4L 表本月最后一个周三。

    • 0 0 13 L * ?
      每月的最后一天的 13:00:00 触发一次。

    • 0 0 13 ? * L
      (每月的)每周的最后一天(即周六)的 13:00:00 触发一次。

    • 0 0 13 ? * 4L
      (每月的)最后一个周三的 13:00:00 触发一次。

  • W 字母 W(Weekday),表 最接近指定日的工作日 (周一至周五),只能在「日」域中使用。此用法 只在当前月内计算,不会超出本月范围 。如本月最后一天是 31 日(周天),那么31W 表示当月的 29 日(周五)。也可用 LW 来指定当前月的最后一个工作日。
    • 0 0 13 15W * ?
      • 假设 15 日是周一,表示(每月的)15 日的 13:00:00 触发一次。
      • 假设 15 日是周六,表示(每月的)14 日的 13:00:00 触发一次。
      • 假设 15 日是周天,表示(每月的)16 日的 13:00:00 触发一次。
  • C 字母 C(Calendar),表 和 Calendar 联系后计算过的值,只能在「日」或「周」域中使用。

    • 0 0 0 5C * ?
      网上没找到结合实例的解释,没搞懂。遇上再说。

    • 0 0 0 ? * 5C
      网上没找到结合实例的解释,没搞懂。遇上再说。

  • # 井号,a#b 每月的第 b 个周(a-1),只能在「周」域中使用。

    • 0 0 0 ? * 1#3
      每月的第 3 个周天的 00:00:00 触发。

    • 0 0 0 ? * 3#2
      每月的第 2 个周二的 00:00:00 触发。

综合实例

  • 0 */1 * * * ?
    每隔 1 分钟触发一次

  • 0 0/1 * * * ?
    每隔 1 分钟触发一次

  • 0 0 22 * * ?
    每天 22:00:00 触发一次

  • 0 0 22 ? * *
    每天 22:00:00 触发一次

  • 0 0 3 * * ? 2020
    2020 年的每天的 03:00:00 触发一次

  • 0 0 3 ? * 6L 2019-2021
    2019 年至 2021 年的每月的最后一个周五的 03:00:00 触发一次

  • 0 0-5 14 * * ?
    每天 14:00 至 14:05 期间每分钟触发一次

  • 0 0 13 ? 3 WED
    每年 3 月的每个周三的 13:00:00 触发一次

  • 0 0 13 ? 3 WED-SAT
    每年 3 月的每周的周三、周四、周五、周六的 13:00:00 触发一次

  • 0 0 1 1 * ?
    每月 1 号的 01:00:00 触发一次

  • 0 0 23 L * ?
    每月最后一天的 23:00:00 触发一次

  • 0 0 3 ? * L
    每周周六的 03:00:00 触发一次

  • 0 0 3 ? * 6L
    每月的最后一个周五的 03:00:00 触发一次

  • 0 24,30 * * * ?
    每小时的 24 分和 30 分各触发一次

  • 0 0 3 ? * 6#3
    每月的第 3 个周五的 03:00:00 触发一次

cron 表达式生成器

https://cron.qqe2.com/

参考文献

[1] 码农小胖哥. 详解定时任务中的 cron 表达式[EB/OL].https://juejin.im/post/6844904047237955592,2020-01-14,2020-01-14.
[2]Ruthless.cron 表达式详解[EB/OL].https://www.cnblogs.com/linjiqin/p/3178452.html,2013-07-08.
[3]MicroFocus.UnderstandingCronSyntaxInTheJobScheduler[EB/OL].https://www.netiq.com/documentation/cloud-manager-2-5/ncm-reference/data/bexyssf.html,.