cron表达式的结构

cron表达式是一个字符串,有5位、6位、7位之分,不同位数之间以空格分隔

位数 每位的含义
5位: * 分、时、天、月、周
6位: 秒、分、时、天、月、周
7位: * 秒、分、时、天、月、周、年

其语法格式为:

“秒域 分域 时域 日域 月域 周域 年域”

在大部分情况下会省略年这一位,成为6位,省略时表示每年。再省略秒,就成为5位。

注意:Linux中的crontab表达式只有5位。

cron每个域的取值范围

域名 可取值 可取符号(仅列部分常用)
秒域 0~59的整数 * - , /
分域 0~59的整数 * - , /
时域 0~23的整数 * - , /
日域 1~31的整数 * - , / ? L
月域 1~12的整数或JAN~DEC * - , /
周域 1~7的整数(星期天为1)或SUN~SAT对于星期,最好使用英文缩写,更加清晰 * - , / ? L #
年域 1970~2099的整数 * - , /

常用字符

  • 【*】:每的意思。在不同的字段上,就代表每秒,每分,每小时等。
  • 【-】:指定值的范围。比如[1-10],在秒字段里就是每分钟的第1到10秒,在分就是每小时的第1到10分钟,以此类推。
  • 【,】:指定某几个值。比如[2,4,5],在秒字段里就是每分钟的第2,第4,第5秒,以此类推。
  • 【/】:指定值的起始和增加幅度。比如[3/5],在秒字段就是每分钟的第3秒开始,每隔5秒生效一次,也就是第3秒、8秒、13秒,以此类推。
  • 【?】:仅用于【日】和【周】字段。因为在指定某日和周几的时候,这两个值实际上是冲突的,所以需要用【?】标识不生效的字段。比如【0 1 ?】就代表每年每月每日每小时的1分0秒触发任务。这里的周就没有效果了。

极少能用到的字符

  • SUN:仅用于【周】字段,表示星期日。也可以用数字1设置。周日到周六分别为SUN,MON,TUE,WED,THU,FRI和SAT,对应数字1,2,3,4,5,6,7。目前Quartz支持。
  • L:即last,用于【日】【周】字段。这里需要注意的是,在不同的字段的不同使用方式,其含义有所差别。
    • 用于日字段:直接使用L代表每个月的最后一天。也支持偏移量的方式,配置[L-1]则代表每月的倒数第二天。
    • 用于周字段:直接使用L代表每周的最后一天,也就是等效于[7]或[SAT],但是如果配合上数字,比如[7L],则代表每个月最后一个周六,等效于[SATL]。目前Quartz支持。
  • #:只能用于周域上,#后面的数字表示第几周,如果不存在这个周的值,则不执行;
    • 例如,”0 0 0 ? 5#2”表示每个月第2个周四零点执行,”15 30 6 ? 7#5”表示每个月第5个周六6:30:15执行,如果某个月不存在第5个周六,则不执行。
1
2
3
4
5
6
7
8
9
10
*    *    *    *    *    *    *
- - - - - - -
| | | | | | |
| | | | | | +----- 年域 (1970 ~ 2099)
| | | | | +---------- 周域 (1 ~ 7 或 SUN ~ SAT) (星期天 为1)
| | | | +--------------- 月域 (1 ~ 12 或 JAN ~ DEC)
| | | +-------------------- 日域 (0 ~ 31)
| | +------------------------- 时域 (0 ~ 23)
| +------------------------------ 分域 (0 ~ 59)
+----------------------------------- 秒域 (0 ~ 59)

一些常用实例

执行时间 cron表达式
每隔5秒钟执行一次 /5 * ?
每隔1分钟执行一次 0 /1 ?
每天凌晨1点执行一次 0 0 1 ?
每天23点55分执行一次 0 55 23
每月最后一天23点55分执行一次 0 55 23 L * ?
每周六9点执行一次 0 0 9 ? * L
每月最后一个周五,每隔2小时执行一次 0 0 /2 ? 6L
每月的第三个星期五上午9:15执行一次 0 15 9 ? * 6#3
在每天中午12点到12:05期间的每1分钟执行 0 0-5 12 ?
表示周一到周五每天上午9:15执行 0 15 9 ? * 2-6
表示周一到周五每天上午9:15执行 0 15 9 ? * MON-FRI
每个月的最后一个星期五上午9:15执行 0 15 9 ? * 6L
每天10点,12点,16点 各执行一次 0 0 10,12,16 ?
朝九晚五工作时间内每半小时执行一次 0 0/30 9-17 ?
每个星期三中午12点执行一次 0 0 12 ? * 4
每年三月的星期三的下午2:10和2:44各执行一次 0 10,44 14 ? 3 4 
每年三月的每周三的14:10分到14:44各执行一次 0 10,44 14 ? 3 WED
每月的第三个星期五上午10:15执行一次 0 15 10 ? * 6#3
每月的第三个星期五上午10:15执行一次 0 15 10 ? * FRI#3
每分钟的第10秒与第20秒都会执行 10,20 ?
每月一日凌晨2点30执行一次 0 30 2 1 * ?

关于的cron执行时区tips:

  1. Cron表达式执行时按照本地时间还是UTC时间取决于实际使用的调度程序。大多数情况下,使用本地时间。但是,一些调度程序(例如AWS Lambda)可能使用UTC时间执行Cron表达式。建议查看使用的调度程序的文档以了解其行为。
  2. 表达式生成器,可以用于验证和生成
  • 在Linux中,Cron表达式执行通常基于系统的本地时间。这意味着Cron作业将按照与系统时区相关的本地时间执行。

可以通过查看系统时区来确认。使用以下命令检查当前系统时区:

1
timedatectl

如果需要,可以使用以下命令设置系统时区:
1
timedatectl set-timezone [时区字符串]

请注意,虽然Cron表达式执行按照本地时间执行,但依赖于系统时间,因此在改变系统时区之后,可能需要使用 systemctl restart cron 命令来重新加载Cron服务,以使Cron作业按新的时区执行。

  • 在Quartz.NET中,默认情况下,Cron表达式执行使用的是本地时间。这与大多数操作系统和应用程序都使用本地时间的原则一致。但是,Quartz.NET也支持使用UTC时间执行Cron表达式,因此可以根据需要进行配置。

  • 在github Action中会提示Actions schedules run at most every 5 minutes using UTC time. 默认按照utc时间