一.Quartz中cron 表达式分析:
quartz 官方源码(org.quartz.CronExpression)解释:
Cron expressions are comprised of 6 required fields and one optional field separated by white space. The fields respectively are described as follows:
(翻译:Cron表达式由6个必填字段和一个由空格分隔的可选字段组成。 这些字段分别描述如下:)
Field Name | Allowed Values | Allowed Special Characters | ||
---|---|---|---|---|
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 (Optional) |
empty, 1970-2199 |
, - * / |
由上表格可见,Quartz中cron表达式可以由最多7个字段构成,即:秒、分、时、日、月、周、年,最后一个字段”年“则可以为空;
对于周几,即 “Day-of-Week” 其值 1,2,3,4,5,6,7分别表示 “SUN,MON,TUE,WED,THU,FRI,SAT”;
二. SpringBoot schedule cron表达式分析:
解析cron expression的源码(org.springframework.scheduling.support.CronSequenceGenerator.class):
1 private void parse(String expression) throws IllegalArgumentException { 2 String[] fields = StringUtils.tokenizeToStringArray(expression, " "); 3 if (!areValidCronFields(fields)) { 4 throw new IllegalArgumentException(String.format( 5 "Cron expression must consist of 6 fields (found %d in "%s")", fields.length, expression)); 6 } 7 setNumberHits(this.seconds, fields[0], 0, 60); 8 setNumberHits(this.minutes, fields[1], 0, 60); 9 setNumberHits(this.hours, fields[2], 0, 24); 10 setDaysOfMonth(this.daysOfMonth, fields[3]); 11 setMonths(this.months, fields[4]); 12 setDays(this.daysOfWeek, replaceOrdinals(fields[5], "SUN,MON,TUE,WED,THU,FRI,SAT"), 8); 13 if (this.daysOfWeek.get(7)) { 14 // Sunday can be represented as 0 or 7 15 this.daysOfWeek.set(0); 16 this.daysOfWeek.clear(7); 17 } 18 }
由上面的代码看Cron表达式必须由6个字段组成,没有‘year’!,重点看setDays方法,此方法转换dayOfWeek的值,找到replaceOrdnal方法源码:
1 /** 2 * Replace the values in the comma-separated list (case insensitive) 3 * with their index in the list. 4 * @return a new String with the values from the list replaced 5 */ 6 private String replaceOrdinals(String value, String commaSeparatedList) { 7 String[] list = StringUtils.commaDelimitedListToStringArray(commaSeparatedList); 8 for (int i = 0; i < list.length; i++) { 9 String item = list[i].toUpperCase(); 10 value = StringUtils.replace(value.toUpperCase(), item, "" + i); 11 } 12 return value; 13 }
上面的代码直接将cronExpression字符串中的 "SUN,MON,TUE,WED,THU,FRI,SAT"分别替换成了”0,1,2,3,4,5,6“;
而且parse方法中注释”// Sunday can be represented as 0 or 7” 即:周日均可用‘0’或’7‘表示。
所以对于springBoot schedule 其值 1,2,3,4,5,6,7分别表示 “MON,TUE,WED,THU,FRI,SAT,SUN”;0也表示SUN;