Cron 表达式详解

Cron 表达式是一个字符串,字符串以 5 或 6 个空格隔开,分为 6 或 7 个域,每一个域代表一个含义,Cron 有如下两种语法格式:

Seconds Minutes Hours DayofMonth Month DayofWeek Year
Seconds Minutes Hours DayofMonth Month DayofWeek
Minutes Hours DayofMonth Month DayofWeek

{秒数} {分钟} {小时} {日期} {月份} {星期} {年份 ( 可为空)}

字段允许值允许的特殊字符
0-59, - * /
0-59, - * /
小时0-23, - * /
日期1-31, - * ? / L W C
月份1-12 或者 JAN-DEC, - * /
星期1-7 或者 SUN-SAT, - * ? / L C #
年(可为空)留空, 1970-2099, - * /

允许值范围: 0~59 , 不允许为空值,若值不合法,调度器将抛出 SchedulerException 异常

"*" 代表每隔 1 秒钟触发

"," 代表在指定的秒数触发,比如 "0,15,45" 代表 0 秒、15 秒和 45 秒时触发任务

"-" 代表在指定的范围内触发,比如 "25-45" 代表从 25 秒开始触发到 45 秒结束触发,每隔 1 秒触发 1 次

"/" 代表触发步进 (step),"/" 前面的值代表初始值 (""等同"0"),后面的值代表偏移量,比如"0/20"或者"/20"代表从 0 秒钟开始,每隔 20 秒钟触发 1 次,即 0 秒触发 1 次,20 秒触发 1 次,40 秒触发 1 次;"5/20"代表 5 秒触发 1 次,25 秒触发 1 次,45 秒触发 1 次;"10-45/20" 代表在 [10,45] 内步进 20 秒命中的时间点触发,即 10 秒触发 1 次,30 秒触发 1 次

分钟

允许值范围: 0~59 , 不允许为空值,若值不合法,调度器将抛出 SchedulerException 异常

"*" 代表每隔 1 分钟触发

"," 代表在指定的分钟触发,比如 "10,20,40" 代表 10 分钟、20 分钟和 40 分钟时触发任务

"-" 代表在指定的范围内触发,比如 "5-30" 代表从 5 分钟开始触发到 30 分钟结束触 发,每隔 1 分钟触发

"/" 代表触发步进 (step),"/" 前面的值代表初始值 (""等同"0"),后面的值代表偏移量,比如"0/25"或者"/25"代表从 0 分钟开始,每隔 25 分钟触发 1 次,即 0 分钟触发 1 次,第 25 分钟触发 1 次,第 50 分钟触发 1 次;"5/25"代表 5 分钟触发 1 次,30 分钟触发 1 次,55 分钟触发 1 次;"10-45/20" 代表在 [10,45] 内步进 20 分钟命中的时间点触发,即 10 分钟触发 1 次,30 分钟触发 1 次

小时

允许值范围: 0~23 , 不允许为空值,若值不合法,调度器将抛出 SchedulerException 异常

"*" 代表每隔 1 小时触发

"," 代表在指定的时间点触发,比如 "10,20,23" 代表 10 点钟、20 点钟和 23 点触发任务

"-" 代表在指定的时间段内触发,比如 "20-23" 代表从 20 点开始触发到 23 点结束触发,每隔 1 小时触发

"/" 代表触发步进 (step),"/" 前面的值代表初始值 (""等同"0"),后面的值代表偏移量,比如"0/1"或者"/1"代表从 0 点开始触发,每隔 1 小时触发 1 次;"1/2" 代表从 1 点开始触发,以后每隔 2 小时触发一次

日期

允许值范围: 1~12 (JAN-DEC), 不允许为空值,若值不合法,调度器将抛出 SchedulerException 异常

"*" 代表每个月都触发

"," 代表在指定的月份触发,比如 "1,6,12" 代表 1 月份、6 月份和 12 月份触发任务

"-" 代表在指定的月份范围内触发,比如 "1-6" 代表从 1 月份开始触发到 6 月份结束触发,每隔 1 个月触发

"/" 代表触发步进 (step),"/" 前面的值代表初始值 (""等同"1"),后面的值代表偏移量,比如"1/2"或者"/2"代表从 1 月份开始触发,每隔 2 个月触发 1 次;"6/6"代表从 6 月份开始触发,以后每隔 6 个月触发一次;"1-6/12" 表达式意味着每年 1 月份触发

星期

允许值范围: 1~7 (SUN-SAT),1 代表星期天 (一星期的第一天),以此类推,7 代表星期六 (一星期的最后一天),不允许为空值,若值不合法,调度器将抛出 SchedulerException 异常

"*" 代表每星期都触发;

"?" 与 {日期} 互斥,即意味着若明确指定 {日期} 触发,则表示 {星期} 无意义,以免引起冲突和混乱

"," 代表在指定的星期约定触发,比如 "1,3,5" 代表星期天、星期二和星期四触发

"-" 代表在指定的星期范围内触发,比如 "2-4" 代表从星期一开始触发到星期三结束触发,每隔 1 天触发

"/" 代表触发步进 (step),"/" 前面的值代表初始值 (""等同"1"),后面的值代表偏移量,比如"1/3"或者"/3"代表从星期天开始触发,每隔 3 天触发 1 次;"1-5/2" 表达式意味着在 [1,5] 范围内,每隔 2 天触发,即星期天、星期二、星期四触发

"L" 如果 {星期} 占位符如果是 "L",即意味着星期的的最后一天触发,即星期六触发,L= 7 或者 L = SAT,因此,"5L" 意味着一个月的最后一个星期四触发

"#" 用来指定具体的周数,"#" 前面代表星期,"#" 后面代表本月第几周,比如 "2#2" 表示本月第二周的星期一,"5#3" 表示本月第三周的星期四,因此,"5L" 这种形式只不过是 "#" 的特殊形式而已

年份

允许值范围: 1970~2099 , 允许为空,若值不合法,调度器将抛出 SchedulerException 异常

"*" 代表每年都触发

"," 代表在指定的年份才触发,比如 "2011,2012,2013" 代表 2011 年、2012 年和 2013 年触发任务

"-" 代表在指定的年份范围内触发,比如 "2011-2020" 代表从 2011 年开始触发到 2020 年结束触发,每隔 1 年触发

"/" 代表触发步进 (step),"/" 前面的值代表初始值 (""等同"1970"),后面的值代表偏移量,比如"2011/2"或者"/2" 代表从 2011 年开始触发,每隔 2 年触发 1 次

注意:除了 {日期} 和{星期}可以使用 "?" 来实现互斥,表达无意义的信息之外,其他占位符都要具有具体的时间含义,且依赖关系为:年 ->月 ->日期(星期)->小时 ->分钟 ->秒数

特殊字符

“*”

”字符被用来指定所有的值。如:"" 在分钟的字段域里表示“每分钟”。

“?”

“?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。 月份中的日期和星期中的日期这两个元素是互斥的,一起时应该通过设置一个问号来表明不想设置那个字段。

“-”

“-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10 点、11 点、12 点”。

“,”

“,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”。

“/”

“/”字符用于指定增量。如:“0/15”在秒域意思是每分钟的 0,15,30 和 45 秒。“5/15”在分钟域表示每小时的 5,20,35 和 50。符号“”在“/”前面(如:/10)等价于 0 在“/”前面(如:0/10)。记住一条本质:表达式的每个数值域都是一个有最大值和最小值的集合,如:秒域和分钟域的集合是 0-59,日期域是 1-31,月份域是 1-12。字符“/”可以帮助你在每个字符域中取相应的数值。如:“7/6”在月份域的时候只有当 7 月的时候才会触发,并不是表示每个 6 月。

“L”

L 是‘last’的省略写法可以表示 day-of-month 和 day-of-week 域,但在两个字段中的意思不同,例如 day-of-month 域中表示一个月的最后一天。如果在 day-of-week 域表示‘7’或者‘SAT’,如果在 day-of-week 域中前面加上数字,它表示一个月的最后几天,例如‘6L’就表示一个月的最后一个星期五。

“W”

字符“W”只允许日期域出现。这个字符用于指定日期的最近工作日。例如:如果你在日期域中写 “15W”,表示:这个月 15 号最近的工作日。所以,如果 15 号是周六,则任务会在 14 号触发。如果 15 好是周日,则任务会在周一也就是 16 号触发。如果是在日期域填写“1W”即使 1 号是周六,那么任务也只会在下周一,也就是 3 号触发,“W”字符指定的最近工作日是不能够跨月份的。字符“W”只能配合一个单独的数值使用,不能够是一个数字段,如:1-15W 是错误的。

“L”和“W”可以在日期域中联合使用,LW 表示这个月最后一周的工作日。

“#”

字符“#”只允许在星期域中出现。这个字符用于指定本月的某某天。例如:“6#3”表示本月第三周的星期五(6 表示星期五,3 表示第三周)。“2#1”表示本月第一周的星期一。“4#5”表示第五周的星期三。

“C”

字符“C”允许在日期域和星期域出现。这个字符依靠一个指定的“日历”。也就是说这个表达式的值依赖于相关的“日历”的计算结果,如果没有“日历”关联,则等价于所有包含的“日历”。如:日期域是“5C”表示关联“日历”中第一天,或者这个月开始的第一天的后 5 天。星期域是“1C”表示关联“日历”中第一天,或者星期的第一天的后 1 天,也就是周日的后一天(周一)。

表达式举例

"0 0 12 * * ?" 每天中午 12 点触发

"0 15 10 ? * *" 每天上午 10:15 触发

"0 15 10 * * ?" 每天上午 10:15 触发

"0 15 10 * * ? *" 每天上午 10:15 触发

"0 15 10 * * ? 2005" 2005 年的每天上午 10:15 触发

"0 * 14 * * ?" 在每天下午 2 点到下午 2:59 期间的每 1 分钟触发

"0 0/5 14 * * ?" 在每天下午 2 点到下午 2:55 期间的每 5 分钟触发

"0 0/5 14,18 * * ?" 在每天下午 2 点到 2:55 期间和下午 6 点到 6:55 期间的每 5 分钟触发

"0 0-5 14 * * ?" 在每天下午 2 点到下午 2:05 期间的每 1 分钟触发

"0 10,44 14 ? 3 WED" 每年三月的星期三的下午 2:10 和 2:44 触发

"0 15 10 ? * MON-FRI" 周一至周五的上午 10:15 触发

"0 15 10 15 * ?" 每月 15 日上午 10:15 触发

"0 15 10 L * ?" 每月最后一日的上午 10:15 触发

"0 15 10 ? * 6L" 每月的最后一个星期五上午 10:15 触发

"0 15 10 ? * 6L 2002-2005" 2002 年至 2005 年的每月的最后一个星期五上午 10:15 触发

"0 15 10 ? * 6#3" 每月的第三个星期五上午 10:15 触发