一文搞懂quartz cron trigger

翻译自http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html

介绍

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

CronTrigger使用“cron表达式”,它能够创建触发时间表,例如:“每周一至周五上午8:00”或“每个月最后一个星期五的凌晨1:30”。

Cron表达式很强大,但可能会让人很困惑。 本教程旨在揭示创建一个cron表达式的一些谜团,为用户提供他们可以在论坛或邮件列表中询问之前可以访问的资源。

格式

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

字段名称 是否必须 取值范围 可选的特殊字符
秒 ( Seconds ) 0-59 , - * /
分 ( Minutes ) 0-59 , - * /
时 ( Hours ) 0-23 , - * /
月里的第几天 ( Day of month ) 1-31 , - * ? / L W
月 ( Month ) 1-12 或者 JAN-DEC , - * /
周里的星期几 ( Day of week ) 1-7 或者 SUN-SAT , - * ? / L #
年 ( Year ) empty, 1970-2099 , - * /

所以cron表达式可以这么简单: * * * * ? * (每秒触发一次)
或者复杂些, 比如: 0/5 14,18,3-39,52 * ? JAN,MAR,SEP MON-FRI 2002-2010

特殊字符

  • * ( all values ,所有值 ) 用于选择字段中的所有值。例如,分钟字段中的“*”表示“每分钟”。

  • ?( no specific value,无特定值 ) 当需要在两个字段之一中指定一个字段的取值,而在另一个字段中的值不要求。例如,如果我希望我的触发器在该月的某个特定日期(例如,第10天)触发,但不关心恰好在一周的哪一天,我会在 Day-of-month 字段放置10 并在 Day-of-week 放置?。请参阅以下示例部分以获得说明。

    • \ 用于指定范围。例如,小时字段中的“10-12”表示“小时10,11和12”。
  • ,用于指定其他值。例如,day-of -week字段中的“MON,WED,FRI”表示“星期一,星期三和星期五”。

  • / 用于指定增量。例如,秒字段中的“0/15”表示“秒0,15,30和45”; 秒字段中的“5/15”表示“秒5,20,35和50”。你也可以在’’字符后指定’/‘ - 在这种情况下’’相当于在’/‘之前有’0’ ( 例如秒字字段设为/15 等价于0/15)。日期字段中的“1/3”表示“从该月的第一天开始每3天触发一次”。

  • L( 最后, last) 对于day-of-month 和 day-of-week两个字段具有不同的含义。
    day-of-month 字段中的值“L”表示“月份的最后一天” ,比如1月的31日,非闰年2月的28日。
    如果在day-of-week字段中单独使用,则仅表示“7”或“SAT”。
    如果在day-of-week 段中使用另一个值后,则表示“该月的最后一个星期几” - 例如“6L”表示“该月的最后一个星期五”。
    还可以指定从该月的最后一天开始的偏移量,例如“L-3”,这意味着该日历月的倒数第三天。使用“L”选项时,重要的是不要指定列表或值范围,因为您会收到令人困惑/意外的结果。

  • W(“工作日”) 用于指定在最接近给定日期的工作日执行(周一至周五)。例如,如果您指定“15W”作为日期字段的值,则含义为:“最近的工作日到该月的15日”。因此,如果15日是星期六,触发器将在14日星期五执行。如果15日是星期日,触发器将在16日星期一执行。如果15日是星期二,那么它将在星期二15日执行。但是,如果您指定“1W”作为日期的值,并且1号是星期六,则触发器将在3号星期触发,因为它不会“跳过”一个月的边界(也就是在本月里找最接近的工作日)。只有当日期是一天,而不是范围或天数列表时,才能指定“W”字符。

L和W字符也可以在日期字段中组合以产生’LW’,这会转换为最后一个工作日

  • # 用于指定当月的第n个星期几。例如,星期几字段中的“6#3”的值意味着“该月的第三个星期五”(6=星期五,#3=该月份的第3个星期五)。其他例子:“2#1”=该月的第一个星期一,“4#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点59中,每隔5分钟执行
0 0/5 14,18 * * ? 每天,下午两点到两点55和下午6点到6点55,每隔5分钟触发
0 0-5 14 * * ? 每天,下午两点到两点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 * ? 从每月的第一天开始,每隔五天,在中午12点触发
11 11 11 11 11 ? 每年的11月11日,11点11分11秒执行(微笑,你懂的)
注意 ?和 * 在day-of-week and day-of-month 两个字段的影响。

后记

指定星期和月日值的支持尚未完成(您必须在其中一个字段中使用’?’字符)。
在您的语言环境中发生“夏令时”更改的早上几小时之间设置触发时间时要小心(对于美国语言环境,这通常是凌晨2:00之前和之后的小时 - 因为时移会导致跳过或重复取决于时间向后移动还是向前跳跃。您可能会发现此维基百科条目有助于确定您的语言环境的细节:
https://secure.wikimedia.org/wikipedia/en/wiki/Daylight_saving_time_around_the_world