cron表达式主要应用于quartz中,在linux中也有用到,主要功能是设置一个定时器,当到达特定时间时触发任务。
cron表达式主要由七个部分组成,这七个部分分别是秒、分、时、日、月、周、年,每个部分之间由空格分离,顺序必须按照以上顺序,其中年可以省略不写。如:
10 12 9 24 11 ? //表示每年的11月24日9点12分10秒
10 12 9 24 11 ?2012 //表示2012年的11月24日9点12分10秒
下面具体来看每个部分能够取的值:
其中月的允许值也可以为月份的英文简写,如JAN, FEB…DEC;
日表示每月的第几天,也就是几号;
周表示星期几,1表示星期天,2表示星期一,7表示星期六,也可以用英文简写,如SUN, SAT...
特殊字符解释:
* 表示这个部分的所有合法值,如秒上的*表示每一秒,分上的*表示每一分;
, 用来指定一个值列表,如只想在每分钟10秒,13秒和21秒这三个时间点上触发,则用:
10,13,20 * * * * ?
如果只想在每天的7点,11点和20点0分0秒触发,则用:
0 0 7,11,20 * * ?
- 用于指定一个范围,例如在每天的14点在20点之间(包括14和20)每个整点0分0秒都触发一次,可以用:
0 0 14-20 * * ?
/ 用来指定一个递增的时间,例如要在每隔月3号0点0分0秒开始(包括3号),每隔5天触发一次(3,8,13…),则用:
0 0 0 3/5 * ?
也就是说, /左边的数字表示起始值,右边的数字表示步长
如果想要在每月2号0点0分0秒号到11号0点0分0秒范围内每隔3天触发一次,则用:
0 0 0 2-11/3 * ?
? 这个字符只能用在日或者周这两个部分上,表示忽略这个部分的值。之所以要用到这个字符,是因为有时日和周这个两个部分是冲突的,例如下面的cron表示式:
0 0 0 11 * 4
表示每个月的11号星期四0点0分0秒这一天触发。但是,一个月的11号也可能不是星期四。所以当我们制定了日或者周这两者之中的一个时,另一个就不用管另外一个的值了,直接用?来忽略它。
例如每个月的13号0点0分0秒触发,则用:
0 0 0 13 * ?
要注意的是,一般如果日或者周其中之一有值的话,另一个就取?;如果这两者都是取所有值*(如每天的16点0分0秒触发),则一般把周设为?,把日设为*:
0 0 16 * * ?
L 只能用在日和周这两个部分上。当用在日上是,表示每个月的最后一天,如8月的最后一天为31号,9月最后一天为30号;
如每个月最后一天的14点29分56秒触发:
56 29 14 L * ?
如果L用在周上,表示每个月最后一周的星期几,如5L表示每个月最后一个周的星期四;
例如每个月最后一周的星期三0点0分0秒触发:
0 0 0 ? * 4L
W 表示工作日(即星期一到星期五),只能用在日上,用来指定每个月离特定日最近的一个工作日,如12L,表示当月内离12号最近的一个工作日触发,如果当天就是工作日,则当天就触发。注意不能跨月,最近的工作日必须和指定的那天是同一个月内的。假设取离31号最近的工作日(31W),同时31号为星期天;这时只能取该月的29号(星期五),而不能取下一个月的1号。
# 只能用在周上,表示月份中的第几周的星期几。如5#2表示第2周的星期四,也就是第二个周四。
如九月份的第三个周五14点29分37秒触发:
37 29 14 ? 9 6#3
注意点(个人看法,不知道对错):
在某些情况下,cron表达式只是用来限制触发的时间范围(也即只能在这个时间范围内触发),而不是设置触发时间的起始点。
例如:
如果我们想要在12月18号0点0分0秒触发,以后每隔三天触发一次,开始时可能会这样写:
0 0 0 18/3 12 ?
但是实际结果却并不是想要的结果(我也不知道正确的表达式该怎么写)。
这个表达式实际限制了触发时间,也就是只能在每年的12月内触发,同时只能以12月18号为开始触发时间。
所以实际的触发时间是:
2015.12.18
2015.12.21
2015.12.24
2015.12.27
2015.12.30
2016.12.18
2016.12.21
….
之所以会跳转到2016年,是因为我们并没有限制年份,所以当2015年的12月走完后,就会跳到2016年的12月。
如果我们限定了年份为2015年:
0 0 0 18/3 12 ? 2015
那么触发时间为:
2015.12.18
2015.12.21
2015.12.24
2015.12.27
2015.12.30
之后就没有了,表示在2015年12月内,从12月18号开始,每隔三天触发一次。所以只能在2015年12月内触发。
其他情况也类似,如果其他部分也写了具体数值,则表示只能在那个时间内触发,如
0 0 2/5 18 12 ? 2015
表示在2015年12月18号内,从2点开始,每隔5个小时触发一次;过了2015年12月18号就不在触发了。
同时,cron表达式也无法支持多时间段,比如从9点30开始到11点30,和从13点到15点,每15分钟执行一次。
下面是一些从其他地方收集的cron表示式例子:
用法 |
表达式 |
每天的从 5:00 PM 至 5:59 PM 中的每分钟触发 |
0 * 17 * * ? |
每天的从 11:00 PM 至 11:55 PM 中的每五分钟触发 |
0 0/5 23 * * ? |
|
|
每天的从 5:00 AM 至 5:05 AM 中的每分钟触发 |
0 0-5 5 * * ? |
每天的 3:00 AM |
0 0 3 * * ? |
每天的 3:00 AM (另一种写法) |
0 0 3 ? * * |
每天的 12:00 PM (中午) |
0 0 12 * * ? |
在 2005 中每天的 10:15 AM |
0 15 10 * * ? 2005 |
在每个周一,二, 三和周四的 10:15 AM |
0 15 10 ? * MON-FRI |
每月15号的 10:15 AM |
0 15 10 15 * ? |
每月最后一天的 10:15 AM |
0 15 10 L * ? |
每月最后一个周五的 10:15 AM |
0 15 10 ? * 6L |
在 2002, 2003, 2004, 和 2005 年中的每月最后一个周五的 10:15 AM |
0 15 10 ? * 6L 2002-2005 |
每月第三个周五的 10:15 AM |
0 15 10 ? * 6#3 |
每月从第一天算起每五天的 12:00 PM (中午) |
0 0 12 1/5 * ? |
每一个 11 月 11 号的 11:11 AM |
0 11 11 11 11 ? |
三月份每个周三的 2:10 PM 和 2:44 PM |
0 10,44 14 ? 3 WED |