master
parent
d49d6bfc9b
commit
10c52408b2
|
|
@ -19,173 +19,132 @@ package com.njzscloud.common.sichen.support;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a parser and evaluator for unix-like cron expressions. Cron
|
* 提供类 Unix 风格 Cron 表达式的解析器和求值器。Cron 表达式能够指定复杂的时间组合,
|
||||||
* expressions provide the ability to specify complex time combinations such as
|
* 例如“每周一至周五的上午 8:00”或“每月最后一个周五的凌晨 1:30”。
|
||||||
* "At 8:00am every Monday through Friday" or "At 1:30am every
|
*
|
||||||
* last Friday of the month".
|
|
||||||
* <P>
|
* <P>
|
||||||
* Cron expressions are comprised of 6 required fields and one optional field
|
* Cron 表达式由 6 个必填字段和 1 个可选字段组成,字段之间通过空格分隔。各字段的详细说明如下:
|
||||||
* separated by white space. The fields respectively are described as follows:
|
|
||||||
*
|
*
|
||||||
* <table cellspacing="8">
|
* <table cellspacing="8">
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th align="left">Field Name</th>
|
* <th align="left">字段名称</th>
|
||||||
* <th align="left"> </th>
|
* <th align="left"> </th>
|
||||||
* <th align="left">Allowed Values</th>
|
* <th align="left">允许值</th>
|
||||||
* <th align="left"> </th>
|
* <th align="left"> </th>
|
||||||
* <th align="left">Allowed Special Characters</th>
|
* <th align="left">允许的特殊字符</th>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td align="left"><code>Seconds</code></td>
|
* <td align="left"><code>秒(Seconds)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>0-59</code></td>
|
* <td align="left"><code>0-59</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>, - * /</code></td>
|
* <td align="left"><code>, - * /</code></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td align="left"><code>Minutes</code></td>
|
* <td align="left"><code>分(Minutes)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>0-59</code></td>
|
* <td align="left"><code>0-59</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>, - * /</code></td>
|
* <td align="left"><code>, - * /</code></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td align="left"><code>Hours</code></td>
|
* <td align="left"><code>时(Hours)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>0-23</code></td>
|
* <td align="left"><code>0-23</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>, - * /</code></td>
|
* <td align="left"><code>, - * /</code></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td align="left"><code>Day-of-month</code></td>
|
* <td align="left"><code>日(Day-of-month)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>1-31</code></td>
|
* <td align="left"><code>1-31</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>, - * ? / L W</code></td>
|
* <td align="left"><code>, - * ? / L W</code></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td align="left"><code>Month</code></td>
|
* <td align="left"><code>月(Month)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>0-11 or JAN-DEC</code></td>
|
* <td align="left"><code>0-11 或 JAN-DEC(一月至十二月)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>, - * /</code></td>
|
* <td align="left"><code>, - * /</code></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td align="left"><code>Day-of-Week</code></td>
|
* <td align="left"><code>周(Day-of-Week)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>1-7 or SUN-SAT</code></td>
|
* <td align="left"><code>1-7 或 SUN-SAT(周日至周六)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>, - * ? / L #</code></td>
|
* <td align="left"><code>, - * ? / L #</code></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td align="left"><code>Year (Optional)</code></td>
|
* <td align="left"><code>年(Year,可选)</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>empty, 1970-2199</code></td>
|
* <td align="left"><code>空值、1970-2199</code></td>
|
||||||
* <td align="left"> </th>
|
* <td align="left"> </th>
|
||||||
* <td align="left"><code>, - * /</code></td>
|
* <td align="left"><code>, - * /</code></td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
* <P>
|
* <P>
|
||||||
* The '*' character is used to specify all values. For example, "*"
|
* '*' 字符用于指定“所有可能的值”。例如,在“分钟”字段中使用 "*" 表示“每分钟”。
|
||||||
* in the minute field means "every minute".
|
|
||||||
* <P>
|
* <P>
|
||||||
* The '?' character is allowed for the day-of-month and day-of-week fields. It
|
* '?' 字符仅允许在“日(Day-of-month)”和“周(Day-of-Week)”字段中使用,
|
||||||
* is used to specify 'no specific value'. This is useful when you need to
|
* 用于表示“不指定具体值”。当你需要在这两个字段中的一个指定条件,而另一个无需指定时,该字符非常有用。
|
||||||
* specify something in one of the two fields, but not the other.
|
|
||||||
* <P>
|
* <P>
|
||||||
* The '-' character is used to specify ranges For example "10-12" in
|
* '-' 字符用于指定时间范围。例如,在“小时”字段中使用 "10-12" 表示“上午 10 点、11 点和中午 12 点”。
|
||||||
* the hour field means "the hours 10, 11 and 12".
|
|
||||||
* <P>
|
* <P>
|
||||||
* The ',' character is used to specify additional values. For example
|
* ',' 字符用于指定多个额外的取值。例如,在“周”字段中使用 "MON,WED,FRI" 表示“周一、周三和周五”。
|
||||||
* "MON,WED,FRI" in the day-of-week field means "the days Monday,
|
|
||||||
* Wednesday, and Friday".
|
|
||||||
* <P>
|
* <P>
|
||||||
* The '/' character is used to specify increments. For example "0/15"
|
* '/' 字符用于指定递增步长。例如,在“秒”字段中使用 "0/15" 表示“第 0 秒、15 秒、30 秒和 45 秒”;
|
||||||
* in the seconds field means "the seconds 0, 15, 30, and 45". And
|
* 而 "5/15" 在“秒”字段中表示“第 5 秒、20 秒、35 秒和 50 秒”。在 '/' 前指定 '*' 等价于以 0 作为起始值。
|
||||||
* "5/15" in the seconds field means "the seconds 5, 20, 35, and
|
* 本质上,表达式的每个字段都对应一组可启用或禁用的数字集合:秒和分的范围是 0-59,小时是 0-23,
|
||||||
* 50". Specifying '*' before the '/' is equivalent to specifying 0 is
|
* 日是 1-31,月是 0-11(对应 JAN 至 DEC)。'/' 字符的作用是在指定集合中启用“每隔 n 个”的取值。
|
||||||
* the value to start with. Essentially, for each field in the expression, there
|
* 需要注意一个细节:在“月”字段中使用 "7/6" 仅会启用“7 月”,并不表示“每 6 个月”。
|
||||||
* is a set of numbers that can be turned on or off. For seconds and minutes,
|
|
||||||
* the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to
|
|
||||||
* 31, and for months 0 to 11 (JAN to DEC). The "/" character simply helps you turn
|
|
||||||
* on every "nth" value in the given set. Thus "7/6" in the
|
|
||||||
* month field only turns on month "7", it does NOT mean every 6th
|
|
||||||
* month, please note that subtlety.
|
|
||||||
* <P>
|
* <P>
|
||||||
* The 'L' character is allowed for the day-of-month and day-of-week fields.
|
* 'L' 字符仅允许在“日(Day-of-month)”和“周(Day-of-Week)”字段中使用,是“last(最后一个)”的缩写,
|
||||||
* This character is short-hand for "last", but it has different
|
* 但在两个字段中的含义有所不同。例如,在“日”字段中使用 "L" 表示“当月的最后一天”——1 月对应 31 日,
|
||||||
* meaning in each of the two fields. For example, the value "L" in
|
* 非闰年的 2 月对应 28 日。若在“周”字段中单独使用 "L",仅表示“7”或“SAT(周六)”;
|
||||||
* the day-of-month field means "the last day of the month" - day 31
|
* 若在其他值后使用,则表示“当月最后一个指定星期几”,例如 "6L" 表示“当月最后一个周五”。
|
||||||
* for January, day 28 for February on non-leap years. If used in the
|
* 你也可以指定相对于月末的偏移量,例如 "L-3" 表示“当月的倒数第三天”。
|
||||||
* day-of-week field by itself, it simply means "7" or
|
* <i>注意:使用 'L' 选项时,请勿同时指定多个取值(列表)或范围,否则会得到混乱或不符合预期的结果。</i>
|
||||||
* "SAT". But if used in the day-of-week field after another value, it
|
|
||||||
* means "the last xxx day of the month" - for example "6L"
|
|
||||||
* means "the last friday of the month". You can also specify an offset
|
|
||||||
* from the last day of the month, such as "L-3" which would mean the third-to-last
|
|
||||||
* day of the calendar month. <i>When using the 'L' option, it is important not to
|
|
||||||
* specify lists, or ranges of values, as you'll get confusing/unexpected results.</i>
|
|
||||||
* <P>
|
* <P>
|
||||||
* The 'W' character is allowed for the day-of-month field. This character
|
* 'W' 字符仅允许在“日(Day-of-month)”字段中使用,用于指定“距离给定日期最近的工作日(周一至周五)”。
|
||||||
* is used to specify the weekday (Monday-Friday) nearest the given day. As an
|
* 例如,若在“日”字段中指定 "15W",含义是“当月 15 日附近最近的工作日”:如果 15 日是周六,
|
||||||
* example, if you were to specify "15W" as the value for the
|
* 则触发时间为 14 日(周五);如果 15 日是周日,则触发时间为 16 日(周一);如果 15 日是周二,
|
||||||
* day-of-month field, the meaning is: "the nearest weekday to the 15th of
|
* 则触发时间为 15 日(周二)本身。若指定 "1W" 且 1 日是周六,触发时间会是 3 日(周一),
|
||||||
* the month". So if the 15th is a Saturday, the trigger will fire on
|
* 因为该字符不会“跨越”月份的边界。'W' 字符仅能在“日”字段指定单个日期时使用,
|
||||||
* Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the
|
* 不能用于日期范围或多个日期列表。
|
||||||
* 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th.
|
|
||||||
* However if you specify "1W" as the value for day-of-month, and the
|
|
||||||
* 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not
|
|
||||||
* 'jump' over the boundary of a month's days. The 'W' character can only be
|
|
||||||
* specified when the day-of-month is a single day, not a range or list of days.
|
|
||||||
* <P>
|
* <P>
|
||||||
* The 'L' and 'W' characters can also be combined for the day-of-month
|
* 'L' 和 'W' 字符可在“日(Day-of-month)”字段中组合使用,形成 "LW",含义是“当月的最后一个工作日”。
|
||||||
* expression to yield 'LW', which translates to "last weekday of the
|
|
||||||
* month".
|
|
||||||
* <P>
|
* <P>
|
||||||
* The '#' character is allowed for the day-of-week field. This character is
|
* '#' 字符仅允许在“周(Day-of-Week)”字段中使用,用于指定“当月第 n 个星期几”。
|
||||||
* used to specify "the nth" XXX day of the month. For example, the
|
* 例如,在“周”字段中使用 "6#3" 表示“当月第三个周五”(6 对应周五,"#3" 对应第三个)。
|
||||||
* value of "6#3" in the day-of-week field means the third Friday of
|
* 其他示例:"2#1" 表示“当月第一个周一”,"4#5" 表示“当月第五个周三”。
|
||||||
* the month (day 6 = Friday and "#3" = the 3rd one in the month).
|
* 注意:若指定了 "#5" 但当月不存在对应的第 5 个星期几,则该月不会触发任务。
|
||||||
* Other examples: "2#1" = the first Monday of the month and
|
* 此外,使用 '#' 字符时,“周”字段中只能包含一个表达式(例如 "3#1,6#3" 是无效的,因为它包含两个表达式)。
|
||||||
* "4#5" = the fifth Wednesday of the month. Note that if you specify
|
|
||||||
* "#5" and there is not 5 of the given day-of-week in the month, then
|
|
||||||
* no firing will occur that month. If the '#' character is used, there can
|
|
||||||
* only be one expression in the day-of-week field ("3#1,6#3" is
|
|
||||||
* not valid, since there are two expressions).
|
|
||||||
* <P>
|
* <P>
|
||||||
* <!--The 'C' character is allowed for the day-of-month and day-of-week fields.
|
* <!--'C' 字符仅允许在“日(Day-of-month)”和“周(Day-of-Week)”字段中使用,是“calendar(日历)”的缩写。
|
||||||
* This character is short-hand for "calendar". This means values are
|
* 这意味着取值会根据关联的日历(若有)进行计算;若未关联日历,则等价于使用全包含日历。
|
||||||
* calculated against the associated calendar, if any. If no calendar is
|
* 在“日”字段中使用 "5C" 表示“日历中包含的、5 日或 5 日之后的第一天”;
|
||||||
* associated, then it is equivalent to having an all-inclusive calendar. A
|
* 在“周”字段中使用 "1C" 表示“日历中包含的、周日或周日之后的第一天”。-->
|
||||||
* value of "5C" in the day-of-month field means "the first day included by the
|
|
||||||
* calendar on or after the 5th". A value of "1C" in the day-of-week field
|
|
||||||
* means "the first day included by the calendar on or after Sunday".-->
|
|
||||||
* <P>
|
* <P>
|
||||||
* The legal characters and the names of months and days of the week are not
|
* 所有合法字符以及月份、星期几的名称均不区分大小写。
|
||||||
* case sensitive.
|
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* <b>NOTES:</b>
|
* <b>注意事项:</b>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Support for specifying both a day-of-week and a day-of-month value is
|
* <li> 同时指定“日(Day-of-month)”和“周(Day-of-Week)”字段的功能尚未完善,
|
||||||
* not complete (you'll need to use the '?' character in one of these fields).
|
* 你需要在其中一个字段中使用 '?' 字符。</li>
|
||||||
* </li>
|
* <li> 支持“溢出范围”(即范围左侧的数字大于右侧):例如,你可以使用 22-2 表示“晚上 10 点至次日凌晨 2 点”,
|
||||||
* <li>Overflowing ranges is supported - that is, having a larger number on
|
* 或使用 NOV-FEB 表示“11 月至次年 2 月”。但需要特别注意,过度使用溢出范围会产生无意义的时间范围,
|
||||||
* the left hand side than the right. You might do 22-2 to catch 10 o'clock
|
* 且 CronExpression 不会对这些无效范围进行特殊判断和处理(例如表达式 "0 0 14-6 ? * FRI-MON" 就是一个无意义的溢出范围示例)。</li>
|
||||||
* at night until 2 o'clock in the morning, or you might have NOV-FEB. It is
|
|
||||||
* very important to note that overuse of overflowing ranges creates ranges
|
|
||||||
* that don't make sense and no effort has been made to determine which
|
|
||||||
* interpretation CronExpression chooses. An example would be
|
|
||||||
* "0 0 14-6 ? * FRI-MON". </li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Sharada Jambula, James House
|
* @author 沙拉达·詹布拉、詹姆斯·豪斯
|
||||||
* @author Contributions from Mads Henderson
|
* @author 贡献者:麦兹·亨德森
|
||||||
* @author Refactoring from CronTrigger to CronExpression by Aaron Craven
|
* @author 重构者:艾伦·克雷文(将功能从 CronTrigger 重构为 CronExpression)
|
||||||
* <p>
|
* <p>
|
||||||
* Borrowed from quartz v2.3.1
|
* 源自 Quartz 框架 v2.3.1 版本
|
||||||
*/
|
*/
|
||||||
public final class CronExpression {
|
public final class CronExpression {
|
||||||
|
|
||||||
|
|
@ -1160,13 +1119,6 @@ public final class CronExpression {
|
||||||
return integer;
|
return integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Computation Functions
|
|
||||||
//
|
|
||||||
|
|
||||||
/// /////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public Date getTimeAfter(Date afterTime) {
|
public Date getTimeAfter(Date afterTime) {
|
||||||
|
|
||||||
// Computation is based on Gregorian year only.
|
// Computation is based on Gregorian year only.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue