介绍

cron表达式是一个已经存在了很长时间的UNIX工具,因此它的调度功能非常强大且已经经过验证。CronTrigger类的功能是基于cron的调度功能实现的。

CronTrigger使用”cron表达式”,可以创建诸如“每周一至周五上午8:00”或“每月最后一个星期五上午1:30”的触发调度时间表(调度计划)。

cron表达式很强大,但是它使用起来也有可能相当混乱(这里大概的意思是说cron的用法相对复杂,容易出错)。本教程旨在解决创建cron表达式的一些谜题,为用户提供一个资源,让他们可以在论坛或邮件列表中提问之前访问这个教程(减少在论坛或者邮件中的提问)。

格式

cron表达式是由空格分隔的6或7个字段组成的字符串。字段可以包含任何允许的值,以及该字段允许的特殊字符的各种组合。这些字段如下所示:

字段名称 是否必须 允许的值 允许的特殊字符
秒种(Seconds) 0-59 , - * /
分钟(Minutes) 0-59 , - * /
小时(Hours) 0-23 , - * /
日(Day of month) 1-31 , - * ? / L W
月(Month) 1-12 or JAN-DEC , - * /
星期(Day of week) 1-7 or SUN-SAT , - * ? / L #
年(Year) empty(也就是不填任何值), 1970-2099 , - * /

译者注:这里可以看出一个cron表达式中年(Year)字段是非必须的,如果不填写此字段可以认为它其实就是*值。

所以cron表达式可以像这样简单:* * * * ? *,或更复杂,如这个例子所示:0/5 14,18,39,52 * ? JAN,MAR,SEP MON-FRI 2002-2010

特殊字符

  • ****:代表所有值 - 用于选择一个字段中的所有值。例如,分钟字段(Minutes)中的”“表示 “每分钟”。
  • **?**:代表没有具体的值 - 当你需要定义两个字段中的其中一个,另一个不需要定义id时候就十分有用(其实主要就是用在Day of month和Day of week的互斥关系中)。例如,例如我想我的触发器每月的某一日(例如第十日)触发,但是我不需要关注当天是星期几,因此我只需要把’10’设置在Day of month字段,把’?’设置在Day of week字段即可。可以参阅下面的例子来进一步了解。
  • **-**:用于指定范围值。例如Hours字段中的”10-12”表示”10,11和12”小时(就是一个范围值)。
  • **,**:用于指定附加值。例如Day of week字段中的”MON,WED,FRI”表示 “星期一,星期三和星期五”。
  • **/**:用于指定增量(格式是:”初始值/增量”)。例如在Seconds字段中”0/15”表示秒数范围取值”0,15,30和45”,Seconds字段中”5/15”表示秒数范围取值”5,20,35和50”。上一个例子说明了,你可以在”/“前取非零值(其实也就是初始值不为0),例如Day of month字段中”1/3”表示从月份的第一天起每三天(触发一次)。
  • L:英文单词”last”的缩写,含义和last一致。
  • W:英文单词”weekday”的缩写,即工作日(星期一到星期五)。

注意:

'L''W'字符可以Day of month字段合并使用,也就是在Day of month字段中使用'LW',转换为“月份的最后一个工作日”。

例如:"0 0 12 1LW * ?"表示每个月的最后一个工作日中午12点触发。
  • **#*:用于指定月份的”第n个”星期XXX(格式:n#p,表示月份的第p个星期n,n由1开始,1表示星期日)。例如,Day of week字段的中”6#3”表示该月的第三个星期五(6表示星期五,#3表示第三个星期)。例如:”2#1”表示月份的第一个星期一,”4#5”表示月份的第五个星期三。注意最后这个例子,如果你指定了”#5”,并且月份的星期数不超过5个,那么该月份不会触发任何调度。

注意:

月份和星期缩写对应的合法字符不区分大小写。例如:MON与mon相同。

例子

这里有一些完整的例子:

表达式 含义
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分结束
0 0/5 14 * * ? 每天下午2点开始,每天下午2点55分结束,每5分钟触发一次
0 0/5 14,18 * * ? 从下午2点开始,每天5分钟触发,结束于下午2点55分,每天5点钟触发,每天晚上6点开始,结束于下午6点55分
0 0-5 14 * * ? 每天下午2点开始,结束于下午2点05分,每分钟触发
0 10,44 14 ? 3 WED 在3月份的每个星期三下午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 L-2 * ? 在每个月的倒数第二天的上午10点15分触发
0 15 10 ? * 6L 每个月的最后一个星期五上午10点15分触发
0 15 10 ? * 6L 2002-2005 2002年,2003年,2004年和2005年每个月的最后一个星期五上午10点15分触发
0 15 10 ? * 6#3 每个月的第三个星期五上午10点15分触发
0 0 12 1/5 * ? 从每月的第一天开始,每个月每隔5天下午12点(中午)触发
0 11 11 11 11 ? 每11月11日上午11点11分触发

注意:

请注意'?''*'在日(Day of month)和星期(Day of week)中的作用。

注意事项

  • 目前不完全支持同时定义Day of week和Day of month两个字段(你必须在这两个字段其中之一使用’?’。其实这样做的目的是这两个字段是互斥的)。
  • 你需要注意如果触发时间设置在凌晨的几个小时,你的语言环境(locale)有可能会因为“夏令时”(对于美国地区,这通常是凌晨2点之前和之后的一个小时)而发生变化 - 此时,时间迁移有可能会发生跳跃或者重复(这里是指同一个时刻重复两次,因为时间发生了回拨),这取决于时间是向后移动还是向前移动。你可以从维基百科上查找资料确定你所在地区的具体情况,链接是:https://secure.wikimedia.org/wikipedia/en/wiki/Daylight_saving_time_around_the_world

原文链接:crontrigger