1、cron表达式支持旬的改造package com.shinfotech.cmes.standard.tools;import java.io.Serializable;import java.text.ParseException;import java.util.Arrays;import java.util.Calendar;import java.util.Collections;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;impo
2、rt java.util.List;import java.util.Locale;import java.util.Map;import java.util.SortedSet;import java.util.StringTokenizer;import java.util.TimeZone;import java.util.TreeSet;import org.quartz.CronTrigger;/* *CronExpression官方版本不支持月份倒数第几天,仅支持月份最后一天L,但业务需求需要知道倒数第二天。 现在加上兼容如2L(每月倒数第二天),10L,5-2L(5号到每月倒数第
3、二天),5-10L,5-L(5号到每月最后一天)的表达式支持。 同时加入了对于旬的支持 例如: 每旬倒数第二天10点15分钟触发 0 15 10 2LX * ? * * author yuch * */SuppressWarnings( rawtypes, unchecked )public class CronExpression implements Serializable, Cloneable private static final long serialVersionUID = 12423409423L; protected static final int SECOND = 0;
4、 protected static final int MINUTE = 1; protected static final int HOUR = 2; protected static final int DAY_OF_MONTH = 3; protected static final int MONTH = 4; protected static final int DAY_OF_WEEK = 5; protected static final int YEAR = 6; protected static final int ALL_SPEC_INT = 99; / * protected
5、 static final int NO_SPEC_INT = 98; / ? protected static final Integer ALL_SPEC = new Integer(ALL_SPEC_INT); protected static final Integer NO_SPEC = new Integer(NO_SPEC_INT); protected static final Map monthMap = new HashMap(20); protected static final Map dayMap = new HashMap(60); protected static
6、 final String BLANK = t; protected static final int CronTrigger_YEAR_TO_GIVEUP_SCHEDULING_AT = 2299; static monthMap.put(JAN, new Integer(0); monthMap.put(FEB, new Integer(1); monthMap.put(MAR, new Integer(2); monthMap.put(APR, new Integer(3); monthMap.put(MAY, new Integer(4); monthMap.put(JUN, new
7、Integer(5); monthMap.put(JUL, new Integer(6); monthMap.put(AUG, new Integer(7); monthMap.put(SEP, new Integer(8); monthMap.put(OCT, new Integer(9); monthMap.put(NOV, new Integer(10); monthMap.put(DEC, new Integer(11); dayMap.put(SUN, new Integer(1); dayMap.put(MON, new Integer(2); dayMap.put(TUE, ne
8、w Integer(3); dayMap.put(WED, new Integer(4); dayMap.put(THU, new Integer(5); dayMap.put(FRI, new Integer(6); dayMap.put(SAT, new Integer(7); private String cronExpression = null; private TimeZone timeZone = null; protected transient TreeSet seconds; protected transient TreeSet minutes; protected tr
9、ansient TreeSet hours; protected transient TreeSet daysOfMonth; protected transient TreeSet months; protected transient TreeSet daysOfWeek; protected transient TreeSet years; protected transient MonLdaySet monLdaySet; protected transient boolean lastdayOfWeek = false; protected transient int nthdayO
10、fWeek = 0; protected transient int nthdayOfXun = 0; protected transient boolean lastdayOfMonth = false; protected transient boolean nearestWeekday = false; protected transient boolean expressionParsed = false; protected transient boolean isLastDayOfXun = false; /* * Constructs a new CronExpression b
11、ased on the specified * parameter. * * param cronExpression * String representation of the cron expression the new object * should represent * throws java.text.ParseException * if the string expression cannot be parsed into a valid * CronExpression */ public CronExpression(String cronExpression) thr
12、ows ParseException if (cronExpression = null) throw new IllegalArgumentException(cronExpression cannot be null); this.cronExpression = cronExpression.toUpperCase(Locale.US); buildExpression(this.cronExpression); /* * * param start * param end * return * throws ParseException */ public List getValidT
13、imesBy(Date start, final Date end) throws ParseException int exprOn = SECOND; boolean isLastDayOfMonth = false; String dayOfMonthExpr = null; String expr = null; StringTokenizer exprsTok = new StringTokenizer(cronExpression, BLANK, false); while (exprsTok.hasMoreTokens() & exprOn 1) dayOfMonthExpr =
14、expr; expr = expr.substring(0, expr.length() - 1); isLastDayOfMonth = true; break; exprOn+; if (isLastDayOfMonth) return getTimesDaysOfMonth( expr, dayOfMonthExpr, start, end); else if(isLastDayOfXun) LinkedList lst = new LinkedList(); lst.addAll(getTimesByStartAndEnd(replaceExpres(11-nthdayOfXun+,D
15、AY_OF_MONTH),start, end); lst.addAll(getTimesByStartAndEnd(replaceExpres(21-nthdayOfXun+,DAY_OF_MONTH),start, end); lst.addAll(getTimesDaysOfMonth(nthdayOfXun+,nthdayOfXun+L,start, end); Collections.sort(lst); return lst; else return getTimesByStartAndEnd(cronExpression, start, end); /* * int exprOn
16、 = SECOND; StringTokenizer exprsTok = new * StringTokenizer(cronExpression, BLANK, false); int last = 0; int * firstDay =0; String dayOfMonthExpr = null; while * (exprsTok.hasMoreTokens() & exprOn 1) dayOfMonthExpr = * expr; expr = expr.substring(0, expr.length() - 1); * if(expr.indexOf(-)!=-1) Stri
17、ng days =expr.split(-); * if(days.length2|days.length1) throw new ParseException( * Day of month values is not implemented +expr, -1); * if(days.length=2) last =StdUtils.integerValue(days1.substring(0, * days1.length() - 1); firstDay =StdUtils.integerValue(days1); if * (firstDay 18) & (firstDay != A
18、LL_SPEC_INT) & * (firstDay != NO_SPEC_INT) throw new ParseException( * Day of month values must be between 1 and 28, -1); else last = * StdUtils.integerValue(expr); exprOn+; if (last 31) & * (last != ALL_SPEC_INT) & (last != NO_SPEC_INT) throw new * ParseException( Day of month values must be betwee
19、n 1 and 31, -1); * * * dayOfMonthCronExpression = cronExpression.replaceAll(dayOfMonthExpr, * L); List list = * getTimesByStartAndEnd(dayOfMonthCronExpression, start, end); * LinkedList lst = new LinkedList(); for (Date date : list) * if(firstDay!=0) date = DateTimeTools.dateIncreaseByDay(date, * -l
20、ast); while(date.getDate()=firstDay) * date=DateTimeTools.dateIncreaseByDay(date, -1); lst.add(date); * /firstDay+; else lst.add(DateTimeTools.dateIncreaseByDay(date, * -last); */ /* * LinkedList lst = new LinkedList(); Date date = start; * while(date.getTime()end.getTime() date = * this.getNextVali
21、dTimeAfter(date); lst.add(date); return lst; */ protected List getTimesDaysOfMonth(String expr,String dayOfMonthExpr,Date start,Date end) throws ParseException int last = 0; int firstDay = 0; if (expr.indexOf(-) != -1) String days = expr.split(-); if (days.length != 2 ) throw new ParseException( Day
22、 of month values is not implemented + expr, -1); if (!.equals(days1) last = StdUtils.integerValue(days1.substring(0,days1.length(); firstDay = StdUtils.integerValue(days0); if (firstDay 18) & (firstDay != ALL_SPEC_INT) & (firstDay != NO_SPEC_INT) throw new ParseException( Day of month values must be
23、 between 1 and 28, -1); else last = StdUtils.integerValue(expr); if (last 31) & (last != ALL_SPEC_INT) & (last != NO_SPEC_INT) throw new ParseException( Day of month values must be between 1 and 31, -1); List list = getTimesByStartAndEnd(replaceExpres(L,DAY_OF_MONTH),start, DateTimeTools.dateIncreas
24、eByMonth(end, 1); LinkedList lst = new LinkedList(); int lastV= last-1; for (Date date : list) if (firstDay != 0) date = DateTimeTools.dateIncreaseByDay(date, -lastV); while (date.getDate() end.getDate() /date = DateTimeTools.dateIncreaseByDay(date, 0); lst.add(date); else lst.add(DateTimeTools.date
25、IncreaseByDay(date, -lastV); return lst; protected List getTimesByStartAndEnd(final String cron, final Date start, final Date end) throws ParseException CronTrigger trigger = new CronTrigger(); trigger.setCronExpression(cron); LinkedList lst = new LinkedList(); if (trigger.getNextFireTime() = null)
26、trigger.setStartTime(start); trigger.setEndTime(end); puteFirstFireTime(null); do Date d = trigger.getNextFireTime(); if (d = null) break; if (d.before(start) trigger.triggered(null); continue; if (d.after(end) break; lst.add(d); trigger.triggered(null); while (true); return lst; /* * Indicates whet
27、her the given date satisfies the cron expression. Note that * milliseconds are ignored, so two Dates falling on different milliseconds * of the same second will always have the same result here. * * param date * the date to evaluate * return a boolean indicating whether the given date satisfies the
28、cron * expression */ public boolean isSatisfiedBy(Date date) Calendar testDateCal = Calendar.getInstance(getTimeZone(); testDateCal.setTime(date); testDateCal.set(Calendar.MILLISECOND, 0); Date originalDate = testDateCal.getTime(); testDateCal.add(Calendar.SECOND, -1); Date timeAfter = getTimeAfter(testDateCal.getTime(); return (timeAfter != null) & (timeAfter.equa
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1