cron表达式支持旬的改造.doc_第1页
cron表达式支持旬的改造.doc_第2页
cron表达式支持旬的改造.doc_第3页
cron表达式支持旬的改造.doc_第4页
cron表达式支持旬的改造.doc_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

.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;import 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号到每月倒数第二天),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;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 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 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 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, new 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 transient 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 nthdayOfWeek = 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 based 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) throws 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 getValidTimesBy(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 =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+,DAY_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;elsereturn getTimesByStartAndEnd(cronExpression, start, end);/* * int exprOn = 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) String 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 =StdUegerValue(days1.substring(0, * days1.length() - 1); firstDay =StdUegerValue(days1); if * (firstDay 18) & (firstDay != ALL_SPEC_INT) & * (firstDay != NO_SPEC_INT) throw new ParseException( * Day of month values must be between 1 and 28, -1); else last = * StdUegerValue(expr); exprOn+; 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); * * * 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, * -last); 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.getNextValidTimeAfter(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 of month values is not implemented + expr,-1);if (!.equals(days1) last = StdUegerValue(days1.substring(0,days1.length();firstDay = StdUegerValue(days0);if (firstDay 18) & (firstDay != ALL_SPEC_INT)& (firstDay != NO_SPEC_INT) throw new ParseException(Day of month values must be between 1 and 28, -1); elselast = StdUegerValue(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.dateIncreaseByMonth(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); elselst.add(DateTimeTools.dateIncreaseByDay(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) 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 whether 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 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.equals(originalDate);/* * Returns the next date/time after the given date/time which * satisfies the cron expression. * * param date * the date/time at which to begin the search for the next valid * date/time * return the next valid date/time * throws ParseException */public Date getNextValidTimeAfter(Date date) throws ParseException return getTimeAfter(date);/* * Returns the next date/time after the given date/time which does * not satisfy the expression * * param date * the date/time at which to begin the search for the next * invalid date/time * return the next valid date/time */public Date getNextInvalidTimeAfter(Date date) long difference = 1000;/ move back to the nearest second so differences will be accurateCalendar adjustCal = Calendar.getInstance(getTimeZone();adjustCal.setTime(date);adjustCal.set(Calendar.MILLISECOND, 0);Date lastDate = adjustCal.getTime();Date newDate = null;/ TODO: (QUARTZ-481) IMPROVE THIS! The following is a BAD solution to/ this problem. Performance will be very bad here, depending on the/ cron expression. It is, however A solution./ keep getting the next included time until its farther than one/ second/ apart. At that point, lastDate is the last valid fire time. We return/ the second immediately following it.while (difference = 1000) newDate = getTimeAfter(lastDate);difference = newDate.getTime() - lastDate.getTime();if (difference = 1000) lastDate = newDate;return new Date(lastDate.getTime() + 1000);/* * Returns the time zone for which this CronExpression will be * resolved. */public TimeZone getTimeZone() if (timeZone = null) timeZone = TimeZone.getDefault();return timeZone;/* * Sets the time zone for which this CronExpression will be * resolved. */public void setTimeZone(TimeZone timeZone) this.timeZone = timeZone;/* * Returns the string representation of the CronExpression * * return a string representation of the CronExpression */public String toString() return cronExpression;/* * Indicates whether the specified cron expression can be parsed into a * valid cron expression * * param cronExpression * the expression to evaluate * return a boolean indicating whether the given expression is a valid cron * expression */public static boolean isValidExpression(String cronExpression) try new CronExpression(cronExpression); catch (ParseException pe) return false;return true;/ / Expression Parsing Functions/ /protected void buildExpression(String expression) throws ParseException expressionParsed = true;try if (seconds = null) seconds = new TreeSet();if (minutes = null) minutes = new TreeSet();if (hours = null) hours = new TreeSet();if (daysOfMonth = null) daysOfMonth = new TreeSet();if (months = null) months = new TreeSet();if (daysOfWeek = null) daysOfWeek = new TreeSet();if (years = null) years = new TreeSet();int exprOn = SECOND;StringTokenizer exprsTok = new StringTokenizer(expression, BLANK,false);while (exprsTok.hasMoreTokens() & exprOn 1) String dayOfXunCronExpression=expr;isLastDayOfXun = true; nthdayOfXun = StdUegerValue(expr.substring(0, expr.length() - 2);if (nthdayOfXun 8) & (nthdayOfXun != ALL_SPEC_INT)& (nthdayOfXun != NO_SPEC_INT) throw new ParseException(Day of Xun values must be between 1 and 8, -1);expr =*;this.cronExpression = this.cronExpression.replaceAll(dayOfXunCronExpression, *);/ throw an exception if L is used with other days of the monthif (exprOn = DAY_OF_MONTH & expr.indexOf(L) != -1& expr.length() 1 & expr.indexOf(,) = 0) throw new ParseException(Support for specifying L and LW with other days of the month is not implemented,-1);/ throw an exception if L is used with other days of the weekif (exprOn = DAY_OF_WEEK & expr.indexOf(L) != -1& expr.length() 1 & expr.indexOf(,) = 0) throw new ParseException(Support for specifying L with other days of the week is not implemented,-1);StringTokenizer vTok = new StringTokenizer(expr, ,);while (vTok.hasMoreTokens() String v = vTok.nextToken();storeExpressionVals(0, v, exprOn);exprOn+;if (exprOn = DAY_OF_WEEK) throw new ParseException(Unexpected end of expression.,expression.length();if (exprOn = s.length() return i;char c = s.charAt(i);if (c = A) & (c = Z) & (!s.equals(L) & (!s.equals(LW) String sub = s.substring(i, i + 3);int sval = -1;int eval = -1;if (type = MO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论