參見 http://gitee.com/xxssyyyyssxx/cron-hms
我們項目中一般會有很多的定時任務,我們怎麼知道這些定時任務是否正常執行了呢?一個基本的想法是,在任務執行前保存一條記錄,任務執行後更新此記錄的結束時間和標記,異常的時候記錄失敗標記和異常信息,然後管理員每天登錄的時候檢查每個任務是否正常執行。如果記錄與設置的執行時刻點匹配,說明任務正常執行了,記錄不存在或者有失敗標記說明任務未正常執行。此謂任務監控。
定時任務一般地由Quartz或者Spring實現,他們都通過一個cron表達式來指定在什麼時刻執行。對於Quartz可以用Aspectj來攔截job,前後記錄;對於Spring的Scheduled,可以用AOP攔截@Scheduled註解或者自定義一個註解,前後記錄。
現在的關鍵問題來了,如何根據cron表達式計算每天的哪些時候執行或者該不該執行?
我們知道,一般地,cron表達式有六個域,分別代表秒、分、時、日、月、星期。每個域可能出現*、/、,、-、數字等。爲了模型簡單化,解析每個域即可知道每個域的哪些點應該執行,那麼一天中,秒、分、時的笛卡爾積即是每天的執行點。任意給定的日期,我們就能知道這個日期應不應該執行(判斷星期、月、日),哪些時刻執行(秒、分、時的笛卡爾積)?
talk is cheap,show me the code。
思路:
1、切割cron表達式
2、轉換每個域
3、計算執行時間點(關鍵算法,解析cron表達式)
4、計算某一天的哪些時間點執行
首先設計表達每個域的枚舉,可以指定位置參數、最小值、最大值。提供根據位置計算枚舉域的靜態方法。再聚合一個JavaBean表示一個域。
/**
* cron表達式某個位置上的一些常量
* @author xiongshiyan at 2018/11/17 , contact me with email [email protected] or phone 15208384257
*/
public enum CronPosition {
SECOND(0 , 0 , 59) ,
MINUTE(1 , 0 , 59) ,
HOUR (2 , 0 , 23) ,
DAY (3 , 1 , 31) ,
MONTH (4 , 1 , 12) ,
WEEK (5 , 0 , 6) ,
YEAR (6 , 2018 , 2099);
/**
* 在cron表達式中的位置
*/
private int position;
/**
* 該域最小值
*/
private Integer min;
/**
* 該域最大值
*/
private Integer max;
CronPosition(int position , Integer min , Integer max){
this.position = position;
this.min = min;
this.max = max;
}
public int getPosition() {
return position;
}
public Integer getMin() {
return min;
}
public Integer getMax() {
return max;
}
public static CronPosition fromPosition(int position){
CronPosition[] values = CronPosition.values();
for (CronPosition field : values) {
if(position == field.position){
return field;
}
}
return null;
}
}
然後就是切割cron表達式、轉換每個域、計算執行時間點(關鍵算法,解析cron表達式)、計算某一天的哪些時間點執行。
/**
* 1.把cron表達式切成域表達式
*
* @param cron cron
* @return 代表每個域的列表
*/
public static List<String> cut(String cron) {
cron = cron.trim();
String[] split = cron.split(CRON_CUT);
return Arrays.asList(split);
}
/**
* 2.cron域表達式轉換爲域
*/
public static List<CronField> convertCronField(String cron) {
List<String> cut = cut(cron);
int size = cut.size();
if (CRON_LEN != size && (CRON_LEN + 1) != size) {
throw new IllegalArgumentException("cron表達式必須有六個域或者七個域(最後爲年)");
}
List<CronField> cronFields = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
CronPosition cronPosition = CronPosition.fromPosition(i);
cronFields.add(new CronField(
cronPosition,
CronShapingUtil.shaping(cut.get(i), cronPosition)
));
}
return cronFields;
}
CronField是表達一個域的,保存域相關信息,並提供計算執行點的方法。
package top.jfunc.cron.pojo;
import top.jfunc.cron.util.CompareUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* cron表達式的域
* @author xiongshiyan
*/
public class CronField {
public static final String STAR = "*";
public static final String COMMA = ",";
public static final String HYPHEN = "-";
public static final String SLASH = "/";
private CronPosition cronPosition;
private String express;
private List<Integer> listCache = null;
public CronField(CronPosition cronPosition, String express) {
this.cronPosition = cronPosition;
this.express = express;
}
public CronPosition getCronPosition() {
return cronPosition;
}
public void setCronPosition(CronPosition cronPosition) {
this.cronPosition = cronPosition;
}
public String getExpress() {
return express;
}
public void setExpress(String express) {
this.express = express;
}
/**
* 是否包含全部的數值
*/
public boolean containsAll(){
return STAR.equals(getExpress());
}
/**
* 3.計算某域的哪些點
*/
public List<Integer> points() {
//緩存計算的
if(null != listCache){
return listCache;
}
listCache = new ArrayList<>(5);
String express = this.getExpress();
CronPosition cronPosition = this.getCronPosition();
Integer min = cronPosition.getMin();
Integer max = cronPosition.getMax();
// *這種情況
if (STAR.equals(express)) {
for (int i = min; i <= max; i++) {
listCache.add(i);
}
return listCache;
}
// 帶有,的情況,分割之後每部分單獨處理
if (express.contains(COMMA)) {
String[] split = express.split(COMMA);
for (String part : split) {
listCache.addAll( new CronField(this.getCronPosition(), part).points());
}
if (listCache.size() > 1) {
//去重
CompareUtil.removeDuplicate(listCache);
//排序
Collections.sort(listCache);
}
return listCache;
}
// 0-3 0/2 3-15/2 5 模式統一爲 (min-max)/step
Integer left;
Integer right;
Integer step = 1;
//包含-的情況
if (express.contains(HYPHEN)) {
String[] strings = express.split(HYPHEN);
left = Integer.valueOf(strings[0]);
CompareUtil.assertRange(cronPosition, left);
//1-32/2的情況
if (strings[1].contains(SLASH)) {
String[] split = strings[1].split(SLASH);
//32
right = Integer.valueOf(split[0]);
CompareUtil.assertSize(left, right);
CompareUtil.assertRange(cronPosition, right);
//2
step = Integer.valueOf(split[1]);
} else {
//1-32的情況
right = Integer.valueOf(strings[1]);
CompareUtil.assertSize(left, right);
CompareUtil.assertRange(cronPosition, right);
}
//僅僅包含/
} else if (express.contains(SLASH)) {
String[] strings = express.split(SLASH);
left = Integer.valueOf(strings[0]);
CompareUtil.assertRange(cronPosition, left);
step = Integer.valueOf(strings[1]);
right = max;
CompareUtil.assertSize(left, right);
} else {
// 普通的數字
Integer single = Integer.valueOf(express);
//星期域上 7 轉換爲 0
if(CronPosition.WEEK == this.cronPosition && 7 == single){
single = 0;
}
CompareUtil.assertRange(cronPosition, single);
listCache.add(single);
return listCache;
}
for (int i = left; i <= right; i += step) {
listCache.add(i);
}
return listCache;
}
@Override
public String toString() {
return "CronField{" +
"cronPosition=" + cronPosition +
", express='" + express + '\'' +
'}';
}
}
然後計算某一天的哪些時刻點執行。
/**
* 4.計算cron表達式在某一天的那些時間執行,精確到秒
* 秒 分 時 日 月 周 (年)
* "0 15 10 ? * *" 每天上午10:15觸發
* "0 0/5 14 * * ?" 在每天下午2點到下午2:55期間的每5分鐘觸發
* "0 0-5 14 * * ?" 每天下午2點到下午2:05期間的每1分鐘觸發
* "0 10,44 14 ? 3 WED" 三月的星期三的下午2:10和2:44觸發
* "0 15 10 ? * MON-FRI" 週一至週五的上午10:15觸發
* ---------------------
*
* @param cron cron表達式
* @param date 時間,某天
* @return 這一天的哪些時分秒執行, 不執行的返回空
*/
public static List<TimeOfDay> calculate(String cron, Date date) {
List<CronField> cronFields = convertCronField(cron);
int year = DateUtil.year(date);
int week = DateUtil.week(date);
int month = DateUtil.month(date);
int day = DateUtil.day(date);
/// 如果包含年域
if (CRON_LEN_YEAR == cronFields.size()) {
CronField fieldYear = cronFields.get(CronPosition.YEAR.getPosition());
if (!assertExecute(year, fieldYear, fieldYear.points())) {
return Collections.emptyList();
}
}
CronField fieldWeek = cronFields.get(CronPosition.WEEK.getPosition());
List<Integer> listWeek = fieldWeek.points();
CronField fieldMonth = cronFields.get(CronPosition.MONTH.getPosition());
List<Integer> listMonth = fieldMonth.points();
CronField fieldDay = cronFields.get(CronPosition.DAY.getPosition());
List<Integer> listDay = fieldDay.points();
///今天不執行就直接返回空
if (!assertExecute(week, fieldWeek, listWeek)
|| !assertExecute(month, fieldMonth, listMonth)
|| !assertExecute(day, fieldDay, listDay)) {
return Collections.emptyList();
}
CronField fieldHour = cronFields.get(CronPosition.HOUR.getPosition());
List<Integer> listHour = fieldHour.points();
CronField fieldMinute = cronFields.get(CronPosition.MINUTE.getPosition());
List<Integer> listMinute = fieldMinute.points();
CronField fieldSecond = cronFields.get(CronPosition.SECOND.getPosition());
List<Integer> listSecond = fieldSecond.points();
List<TimeOfDay> points = new ArrayList<>(listHour.size() * listMinute.size() * listSecond.size());
for (Integer hour : listHour) {
for (Integer minute : listMinute) {
for (Integer second : listSecond) {
points.add(new TimeOfDay(hour, minute, second));
}
}
}
return points;
}
private static boolean assertExecute(int num, CronField cronField, List<Integer> list) {
return CronField.STAR.equals(cronField.getExpress()) || CompareUtil.inList(num, list);
}
一些輔助工具類。替換?JAN-DEC、SUN-SAT等字符串的整形工具類。
package top.jfunc.cron.util;
import top.jfunc.cron.pojo.CronPosition;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author xiongshiyan at 2018/10/12 , contact me with email [email protected] or phone 15208384257
*/
public class CronShapingUtil {
private static final Map<String , String> MONTH_MAP = new HashMap<>(12);
private static final Map<String , String> WEEK_MAP = new HashMap<>(7);
static {
MONTH_MAP.put("JAN" , "1");
MONTH_MAP.put("FEB" , "2");
MONTH_MAP.put("MAR" , "3");
MONTH_MAP.put("APR" , "4");
MONTH_MAP.put("May" , "5");
MONTH_MAP.put("JUN" , "6");
MONTH_MAP.put("JUL" , "7");
MONTH_MAP.put("AUG" , "8");
MONTH_MAP.put("SEP" , "9");
MONTH_MAP.put("OCT" , "10");
MONTH_MAP.put("NOV" , "11");
MONTH_MAP.put("DEC" , "12");
WEEK_MAP.put("SUN" , "0");
WEEK_MAP.put("MON" , "1");
WEEK_MAP.put("TUE" , "2");
WEEK_MAP.put("WED" , "3");
WEEK_MAP.put("THU" , "4");
WEEK_MAP.put("FRI" , "5");
WEEK_MAP.put("SAT" , "6");
}
/**
* 域整形,把某些英文字符串像JAN/SUN等轉換爲相應的數字
*/
public static String shaping(String express , CronPosition cronPosition){
if(cronPosition == CronPosition.MONTH){
express = shapingMonth(express);
}
if(cronPosition == CronPosition.WEEK){
express = shapingWeek(express);
express = express.replace("?" , "*");
}
if(cronPosition == CronPosition.DAY){
express = express.replace("?" , "*");
}
return express;
}
private static String shapingMonth(String express){
Set<Map.Entry<String, String>> entrySet = MONTH_MAP.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
if(express.toUpperCase().contains(entry.getKey())){
express = express.toUpperCase().replace(entry.getKey() , entry.getValue());
}
}
return express;
}
private static String shapingWeek(String express){
Set<Map.Entry<String, String>> entrySet = WEEK_MAP.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
if(express.toUpperCase().contains(entry.getKey())){
express = express.toUpperCase().replace(entry.getKey() , entry.getValue());
}
}
return express;
}
}
時間計算等工具類。
package top.jfunc.cron.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* @author xiongshiyan at 2018/11/18 , contact me with email [email protected] or phone 15208384257
*/
public class DateUtil {
public static final String SDF_DATETIME = "yyyy-MM-dd HH:mm:ss";
public static final String SDF_DATETIME_SHORT = "yyyyMMddHHmmss";
public static final String SDF_DATETIME_MS = "yyyyMMddHHmmssSSS";
public static final String SDF_DATE = "yyyy-MM-dd";
/**
* 字符串轉日期
* @param dateStr 日期字符串
* @return 日期 yyyy-MM-dd HH:mm:ss
*/
public static Date toDate(String dateStr) {
return toDate(dateStr, null);
}
/**
* 日期轉字符串
* @param date 日期
* @return 字符串 yyyy-MM-dd HH:mm:ss
*/
public static String toStr(Date date) {
return toStr(date, SDF_DATETIME);
}
/**
* 日期轉字符串
* @param date 日期
* @param format 格式化字符串
* @return 字符串
*/
public static String toStr(Date date, String format) {
SimpleDateFormat sdf = null;
if (null != format && !"".equals(format)) {
sdf = new SimpleDateFormat(format);
return sdf.format(date);
} else {
sdf = new SimpleDateFormat(SDF_DATETIME);
return sdf.format(date);
}
}
/**
* 字符串轉日期
* @param dateStr 日期字符串
* @param pattern 格式化字符串
* @return 日期
*/
public static Date toDate(String dateStr, String pattern) {
try {
if (null != pattern && !"".equals(pattern)) {
return new SimpleDateFormat(pattern).parse(dateStr);
} else {
return new SimpleDateFormat(SDF_DATETIME).parse(dateStr);
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* 計算某一天是一個月的哪一天
* @param date 日期
* @return 1-31
*/
public static int day(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.DAY_OF_MONTH);
}
/**
* 計算某一天是星期幾
* @param date 日期
* @return 星期幾,星期1是1,星期天是0 0-6
*/
public static int week(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.DAY_OF_WEEK) - 1;
}
/**
* 計算某一天的月份
* @param date 日期
* @return 月份,1開始
*/
public static int month(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.MONTH) + 1;
}
/**
* 計算某一天的年
* @param date 日期
* @return 年
*/
public static int year(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.YEAR);
}
/**
* 計算某一天的時
* @param date 日期
* @return 時 0-23
*/
public static int hour(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.HOUR_OF_DAY);
}
/**
* 計算某一天的分
* @param date 日期
* @return 秒 0-59
*/
public static int minute(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.MINUTE);
}
/**
* 計算某一天的秒
* @param date 日期
* @return 秒 0-59
*/
public static int second(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.SECOND);
}
}
除開解析L、W、C等,至此完成。
https://blog.csdn.net/weixin_40426638/article/details/78959972
https://blog.csdn.net/dabing69221/article/details/19012581
https://blog.csdn.net/ukulelepku/article/details/54310035
項目地址見:
https://gitee.com/xxssyyyyssxx/cron-hms
單元測試:
package top.jfunc.cron;
import org.junit.Assert;
import org.junit.Test;
import top.jfunc.cron.pojo.CronField;
import top.jfunc.cron.pojo.TimeOfDay;
import top.jfunc.cron.util.CronUtil;
import top.jfunc.cron.util.DateUtil;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
* @author xiongshiyan at 2018/11/17 , contact me with email [email protected] or phone 15208384257
*/
public class CronTest {
@Test
public void testCalculate() {
Date date = DateUtil.toDate("2018-11-17 12:00:12");
Assert.assertEquals(2018, DateUtil.year(date));
Assert.assertEquals(11, DateUtil.month(date));
Assert.assertEquals(6, DateUtil.week(date));
Assert.assertEquals(17, DateUtil.day(date));
Assert.assertEquals(12, DateUtil.hour(date));
Assert.assertEquals(0, DateUtil.minute(date));
Assert.assertEquals(12, DateUtil.second(date));
date = DateUtil.toDate("2018-11-18 12:00:12");
Assert.assertEquals(0, DateUtil.week(date));
}
@Test
public void testCut() {
String cron = "0 15 10 ? * * ";
Assert.assertEquals(
Arrays.asList("0", "15", "10", "?", "*", "*"),
CronUtil.cut(cron));
}
@Test
public void testConvertField() {
List<CronField> cronFields = CronUtil.convertCronField("0 0-5 14/2 * * ?");
for (int i = 0; i < 6; i++) {
CronField field = cronFields.get(i);
Assert.assertEquals(field.getCronPosition().getPosition(), i);
}
Assert.assertEquals("0" , cronFields.get(0).getExpress());
Assert.assertEquals("0-5" , cronFields.get(1).getExpress());
Assert.assertEquals("14/2" , cronFields.get(2).getExpress());
Assert.assertEquals("*" , cronFields.get(3).getExpress());
Assert.assertEquals("*" , cronFields.get(4).getExpress());
Assert.assertEquals("*" , cronFields.get(5).getExpress());
List<CronField> fields = CronUtil.convertCronField("0 15 10 ? JAN-NOV MON-FRI");
for (int i = 0; i < 6; i++) {
CronField field = fields.get(i);
Assert.assertEquals(field.getCronPosition().getPosition(), i);
}
Assert.assertEquals("0" , fields.get(0).getExpress());
Assert.assertEquals("15" , fields.get(1).getExpress());
Assert.assertEquals("10" , fields.get(2).getExpress());
Assert.assertEquals("*" , fields.get(3).getExpress());
Assert.assertEquals("1-11" , fields.get(4).getExpress());
Assert.assertEquals("1-5" , fields.get(5).getExpress());
//包含年域的情況
cronFields = CronUtil.convertCronField("0 15 10 ? JAN-NOV MON-FRi 2018");
System.out.println(cronFields);
}
@Test
public void testConvertCronField(){
List<CronField> cronFields = CronUtil.convertCronField("1 0-5 1/3 1,3,4 1-11/2 ?");
Assert.assertEquals(Collections.singletonList(1) , cronFields.get(0).points());
Assert.assertEquals(Arrays.asList(0,1,2,3,4,5) , cronFields.get(1).points());
Assert.assertEquals(Arrays.asList(1,4,7,10,13,16,19,22) , cronFields.get(2).points());
Assert.assertEquals(Arrays.asList(1,3,4) , cronFields.get(3).points());
Assert.assertEquals(Arrays.asList(1,3,5,7,9,11) , cronFields.get(4).points());
Assert.assertEquals(Arrays.asList(0,1,2,3,4,5,6) , cronFields.get(5).points());
}
@Test
public void testCal(){
Date date = DateUtil.toDate("2018-11-18 12:00:12");
List<TimeOfDay> calculate = CronUtil.calculate("0 15 10 ? * *", date);
Assert.assertEquals(Collections.singletonList(new TimeOfDay(10 , 15 , 0)) , calculate);
calculate = CronUtil.calculate("0-5 15 10 ? * *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 15 , 0),
new TimeOfDay(10 , 15 , 1),
new TimeOfDay(10 , 15 , 2),
new TimeOfDay(10 , 15 , 3),
new TimeOfDay(10 , 15 , 4),
new TimeOfDay(10 , 15 , 5)) , calculate);
calculate = CronUtil.calculate("0 1/10 10 ? * *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 11 , 0),
new TimeOfDay(10 , 21 , 0),
new TimeOfDay(10 , 31 , 0),
new TimeOfDay(10 , 41 , 0),
new TimeOfDay(10 , 51 , 0)) , calculate);
calculate = CronUtil.calculate("0 1,4,6,8,10,50 10 ? * *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 4 , 0),
new TimeOfDay(10 , 6 , 0),
new TimeOfDay(10 , 8 , 0),
new TimeOfDay(10 , 10 , 0),
new TimeOfDay(10 , 50 , 0)) , calculate);
calculate = CronUtil.calculate("0 1-30/5 10 ? * *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 6 , 0),
new TimeOfDay(10 , 11 , 0),
new TimeOfDay(10 , 16 , 0),
new TimeOfDay(10 , 21 , 0),
new TimeOfDay(10 , 26 , 0)) , calculate);
calculate = CronUtil.calculate("0 1-30/5 10 ? * SUN", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 6 , 0),
new TimeOfDay(10 , 11 , 0),
new TimeOfDay(10 , 16 , 0),
new TimeOfDay(10 , 21 , 0),
new TimeOfDay(10 , 26 , 0)) , calculate);
calculate = CronUtil.calculate("0 1-30/5 10 ? 11 *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 6 , 0),
new TimeOfDay(10 , 11 , 0),
new TimeOfDay(10 , 16 , 0),
new TimeOfDay(10 , 21 , 0),
new TimeOfDay(10 , 26 , 0)) , calculate);
calculate = CronUtil.calculate("0 1-4,43 10 ? 11 *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 2 , 0),
new TimeOfDay(10 , 3 , 0),
new TimeOfDay(10 , 4 , 0),
new TimeOfDay(10 , 43 , 0)) , calculate);
calculate = CronUtil.calculate("0 1-10/2,43 10 ? 11 *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 3 , 0),
new TimeOfDay(10 , 5 , 0),
new TimeOfDay(10 , 7 , 0),
new TimeOfDay(10 , 9 , 0),
new TimeOfDay(10 , 43 , 0)) , calculate);
calculate = CronUtil.calculate("0 7,1-5/2,5,6 10 ? 11 *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 3 , 0),
new TimeOfDay(10 , 5 , 0),
new TimeOfDay(10 , 6 , 0),
new TimeOfDay(10 , 7 , 0)) , calculate);
calculate = CronUtil.calculate("0 1-6/2,12-27/5 10 ? 11 *", date);
Assert.assertEquals(Arrays.asList(
new TimeOfDay(10 , 1 , 0),
new TimeOfDay(10 , 3 , 0),
new TimeOfDay(10 , 5 , 0),
new TimeOfDay(10 , 12 , 0),
new TimeOfDay(10 , 17 , 0),
new TimeOfDay(10 , 22 , 0),
new TimeOfDay(10 , 27 , 0)) , calculate);
///星期一到星期六執行,星期天不執行就返回空集合
calculate = CronUtil.calculate("0 1-30/5 10 ? * MON-SAT", date);
Assert.assertEquals(Collections.emptyList(), calculate);
}
@Test(expected = IllegalArgumentException.class)
public void testException1(){
Date date = DateUtil.toDate("2018-11-18 12:00:12");
CronUtil.calculate("5-0 15 10 ? * *", date);
}
@Test(expected = IllegalArgumentException.class)
public void testException2(){
Date date = DateUtil.toDate("2018-11-18 12:00:12");
CronUtil.calculate("1-62 15 10 ? * *", date);
}
@Test(expected = IllegalArgumentException.class)
public void testException3(){
Date date = DateUtil.toDate("2018-11-18 12:00:12");
CronUtil.calculate("1 2-78 10 ? * *", date);
}
@Test(expected = IllegalArgumentException.class)
public void testException4(){
Date date = DateUtil.toDate("2018-11-18 12:00:12");
CronUtil.calculate("2 15 25 ? * *", date);
}
@Test(expected = IllegalArgumentException.class)
public void testException5(){
Date date = DateUtil.toDate("2018-11-18 12:00:12");
CronUtil.calculate("2 15 23 2-32 * *", date);
}
@Test(expected = IllegalArgumentException.class)
public void testException6(){
Date date = DateUtil.toDate("2018-11-18 12:00:12");
CronUtil.calculate("2 15 23 3 1-13/2 *", date);
}
}