欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

quartz 节假日

程序员文章站 2022-05-16 18:36:23
...
  1.  
    • 对于排除法定节假日,可以使用HolidayCalendar,但是该类只能排除某一个法定节假日,无法方便的排除一个列
    •  为了方便修改法定节假日,可以将法定节假日的配置放在java properties文件中。
    •  在Spring配置文件中继续配置定时任务,配置如下:

我的定时任务需求是:使用quartz实现每周一至周五,非法定节假日,每天9:30-11:30,13:00-15:00执行定时任务。

 

经过学习quartz,发现使用SimperTrigger和CronTrgger这两种触发器都无法满足这种需求的表达,我始终无法相信强

 

大的quartz绝对不可能无法实现这种需求。

 

  经过别人的指点,终于在一篇法文的blog中找到了类似的解决办法,需要借助于quartz的Calender来实现这种需求,

 

这个过程非常曲折,遇到了很多问题,总体感觉quartz虽然强大,但是社区的活跃程度不够,文档还不是非常完善,

 

这也许是很多开源项目的通病,可能很多复杂一些的需求,直接从文档中无法得到答案,有时候需要自己去阅读源代码,

 

阅读javadoc才能找到答案,解决这一问题后再次印证了那句话,黄天不负有心人,只要你坚持问题总能解决的,

 

下面进入正题。

 

表的节假日,因此需要自己扩展该类,代码如下:

Java代码  quartz 节假日quartz 节假日
  1. private   static  Logger logger = Logger.getLogger(TradeDayCalendar. class );  
  2.       
  3.     //默认的时间格式。   
  4.     public   static  String DEFAULT_DATE_FROMART =  "yyyy-MM-dd" ;  
  5.       
  6.     //时间格式。   
  7.     private  String dateFormat = DEFAULT_DATE_FROMART;  
  8.   
  9.     public  String getDateFormat() {  
  10.         return  dateFormat;  
  11.     }  
  12.   
  13.     /**  
  14.      * 设置日期格式。  
  15.      * @param dateFormat  
  16.      */   
  17.     public   void  setDateFormat(String dateFormat) {  
  18.         this .dateFormat = dateFormat;  
  19.     }  
  20.   
  21.     public  TradeDayCalendar() {  
  22.     }  
  23.   
  24.     public  TradeDayCalendar(Calendar baseCalendar) {  
  25.         super (baseCalendar);  
  26.     }  
  27.   
  28.     public  TradeDayCalendar(TimeZone timeZone) {  
  29.         super (timeZone);  
  30.     }  
  31.   
  32.     public  TradeDayCalendar(Calendar baseCalendar, TimeZone timeZone) {  
  33.         super (baseCalendar, timeZone);  
  34.     }  
  35.   
  36.     /**  
  37.      * 构造一个日历对象,排除指定的那些法定节假日。  
  38.      * @param stringDates 日期列表字符串,一个日期列表字符串,多个日期以逗号隔开,默认的日期格式是 yyyy-MM-dd. 例如 : 2010-1-01,2010-10-01  
  39.      */   
  40.     public  TradeDayCalendar(String stringDates) {  
  41.         this ( null , stringDates);  
  42.     }  
  43.   
  44.     /**  
  45.      *  构造一个日历对象,排除指定的那些法定节假日。  
  46.      *  
  47.      * @param baseCalendar, 与本日历对象关联的基础日历对象,在基础日历对象的基础上再排除指定的法定节假日,可以是null。  
  48.      * @param stringDates 日期列表字符串,一个日期列表字符串,多个日期以逗号隔开,默认的日期格式是 yyyy-MM-dd. 例如 : 2010-1-01,2010-10-01  
  49.      */   
  50.     public  TradeDayCalendar(Calendar baseCalendar, String stringDates) {  
  51.         super (baseCalendar);  
  52.   
  53.         //将日期字符串解析成字符数组。   
  54.         String[] stringDatesArray = stringDates.split("," );  
  55.         Date[] dates = null ;  
  56.         try  {  
  57.             dates = getDatesFromStrings(stringDatesArray);  
  58.         } catch  (ParseException e) {  
  59.             logger.error(e.getMessage());  
  60.         }  
  61.   
  62.         if  (dates !=  null  && dates.length == stringDatesArray.length) {  
  63.             if  (logger.isDebugEnabled())  
  64.                 logger.debug("Excluded dates : "  + stringDates);  
  65.             addExcludedDates(dates);  
  66.         } else  {  
  67.             //某些日期无法解析。   
  68.             throw   new  IllegalArgumentException(  
  69.                     "Some configured dates were invalids (not parseable as "   
  70.                             + dateFormat + "). Full list of configured dates{"   
  71.                             + stringDates +"} valid dates "  +stringDates);  
  72.         }  
  73.     }  
  74.   
  75.     /**  
  76.      * 将日历字符串数组,按照默认的日期格式转换为Date类型的数组。  
  77.      * @param stringDatesArray 日期字符串数组。  
  78.      * @return 转换后的Date型的数组。  
  79.      * @throws ParseException 输入的日期解析出错,日期格式有问题。  
  80.      */   
  81.     private  Date[] getDatesFromStrings(String[] stringDatesArray)  throws  ParseException{  
  82.         if (stringDatesArray== null  || stringDatesArray.length== 0 )  
  83.             return   null ;  
  84.         Date[] dates = new  Date[stringDatesArray.length];  
  85.         for ( int  i= 0 ; i<stringDatesArray.length; i++){  
  86.             String stringDate = stringDatesArray[i];  
  87.             SimpleDateFormat simpleDateFormat = new  SimpleDateFormat(dateFormat);  
  88.             dates[i] = simpleDateFormat.parse(stringDate);  
  89.         }  
  90.         return  dates;  
  91.     }  
  92.       
  93.     /**  
  94.      * 循环添加数组中的日期到被排除的日期列表中,会跳过那些无法解析的日期。  
  95.      */   
  96.     private   void  addExcludedDates(Date[] dates) {  
  97.         for  ( int  i =  0 ; i < dates.length; i++) {  
  98.             Date legalHoliday = dates[i];  
  99.             addExcludedDate(legalHoliday);  
  100.         }  
  101.     }  
private static Logger logger = Logger.getLogger(TradeDayCalendar.class);
	
	//默认的时间格式。
	public static String DEFAULT_DATE_FROMART = "yyyy-MM-dd";
	
	//时间格式。
	private String dateFormat = DEFAULT_DATE_FROMART;

	public String getDateFormat() {
		return dateFormat;
	}

	/**
	 * 设置日期格式。
	 * @param dateFormat
	 */
	public void setDateFormat(String dateFormat) {
		this.dateFormat = dateFormat;
	}

	public TradeDayCalendar() {
	}

	public TradeDayCalendar(Calendar baseCalendar) {
		super(baseCalendar);
	}

	public TradeDayCalendar(TimeZone timeZone) {
		super(timeZone);
	}

	public TradeDayCalendar(Calendar baseCalendar, TimeZone timeZone) {
		super(baseCalendar, timeZone);
	}

	/**
	 * 构造一个日历对象,排除指定的那些法定节假日。
	 * @param stringDates 日期列表字符串,一个日期列表字符串,多个日期以逗号隔开,默认的日期格式是 yyyy-MM-dd. 例如 : 2010-1-01,2010-10-01
	 */
	public TradeDayCalendar(String stringDates) {
		this(null, stringDates);
	}

	/**
	 *  构造一个日历对象,排除指定的那些法定节假日。
	 *
	 * @param baseCalendar, 与本日历对象关联的基础日历对象,在基础日历对象的基础上再排除指定的法定节假日,可以是null。
	 * @param stringDates 日期列表字符串,一个日期列表字符串,多个日期以逗号隔开,默认的日期格式是 yyyy-MM-dd. 例如 : 2010-1-01,2010-10-01
	 */
	public TradeDayCalendar(Calendar baseCalendar, String stringDates) {
		super(baseCalendar);

		//将日期字符串解析成字符数组。
		String[] stringDatesArray = stringDates.split(",");
		Date[] dates = null;
		try {
			dates = getDatesFromStrings(stringDatesArray);
		} catch (ParseException e) {
			logger.error(e.getMessage());
		}

		if (dates != null && dates.length == stringDatesArray.length) {
			if (logger.isDebugEnabled())
				logger.debug("Excluded dates : " + stringDates);
			addExcludedDates(dates);
		} else {
			//某些日期无法解析。
			throw new IllegalArgumentException(
					"Some configured dates were invalids (not parseable as "
							+ dateFormat + "). Full list of configured dates{"
							+ stringDates +"} valid dates " +stringDates);
		}
	}

	/**
	 * 将日历字符串数组,按照默认的日期格式转换为Date类型的数组。
	 * @param stringDatesArray 日期字符串数组。
	 * @return 转换后的Date型的数组。
	 * @throws ParseException 输入的日期解析出错,日期格式有问题。
	 */
	private Date[] getDatesFromStrings(String[] stringDatesArray) throws ParseException{
		if(stringDatesArray==null || stringDatesArray.length==0)
			return null;
		Date[] dates = new Date[stringDatesArray.length];
		for(int i=0; i<stringDatesArray.length; i++){
			String stringDate = stringDatesArray[i];
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
			dates[i] = simpleDateFormat.parse(stringDate);
		}
		return dates;
	}
	
	/**
	 * 循环添加数组中的日期到被排除的日期列表中,会跳过那些无法解析的日期。
	 */
	private void addExcludedDates(Date[] dates) {
		for (int i = 0; i < dates.length; i++) {
			Date legalHoliday = dates[i];
			addExcludedDate(legalHoliday);
		}
	}
Java代码  quartz 节假日quartz 节假日
  1. <bean  class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >  
  2.         <property name="ignoreUnresolvablePlaceholders"  value= "true"  />  
  3.         <property name="location"  value= "classpath:application.properties"  />  
  4.     </bean>  
  5.   
  6.   
  7.   
  8. tradeDays.legalHolidays=2010 - 01 - 01 , 2010 - 10 - 01 , 2010 - 07 - 15   
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="ignoreUnresolvablePlaceholders" value="true" />
		<property name="location" value="classpath:application.properties" />
	</bean>



tradeDays.legalHolidays=2010-01-01,2010-10-01,2010-07-15
Java代码  quartz 节假日quartz 节假日
  1. <!-- 配置监控上交所行情的任务。 -->  
  2.     <bean id="monitorShow2003"   class = "com.cssweb.quote.realtime.oracle.MonitorShow2003"  />  
  3.     <bean id="monitorShow2003JobDetail"   
  4.         class = "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >  
  5.         <property name="targetObject"  ref= "monitorShow2003"  />  
  6.         <property name="targetMethod"  value= "run"  />  
  7.     </bean>  
  8.     <!-- 配置上午监控上交所的任务触发器。 -->  
  9.     <bean id="monitorShow2003AMTrigger"   class = "org.springframework.scheduling.quartz.SimpleTriggerBean" >  
  10.         <property name="jobDetail"  ref= "monitorShow2003JobDetail"  />  
  11.         <!-- 每隔一秒钟(1000 毫秒)执行一次 -->  
  12.         <property name="repeatInterval"  value= "1000" ></property>  
  13.         <property name="calendarName"  value= "tradeTimeAMCalendar" ></property>  
  14.     </bean>  
  15.     <!-- 配置下午监控上交所的任务触发器。 -->  
  16.     <bean id="monitorShow2003PMTrigger"   class = "org.springframework.scheduling.quartz.SimpleTriggerBean" >  
  17.         <property name="jobDetail"  ref= "monitorShow2003JobDetail"  />  
  18.         <!-- 每隔一秒钟(1000 毫秒)执行一次 -->  
  19.         <property name="repeatInterval"  value= "1000" ></property>  
  20.         <property name="calendarName"  value= "tradeTimePMCalendar" ></property>  
  21.     </bean>  
<!-- 配置监控上交所行情的任务。 -->
	<bean id="monitorShow2003" class="com.cssweb.quote.realtime.oracle.MonitorShow2003" />
	<bean id="monitorShow2003JobDetail"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="monitorShow2003" />
		<property name="targetMethod" value="run" />
	</bean>
	<!-- 配置上午监控上交所的任务触发器。 -->
	<bean id="monitorShow2003AMTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		<property name="jobDetail" ref="monitorShow2003JobDetail" />
		<!-- 每隔一秒钟(1000毫秒)执行一次 -->
		<property name="repeatInterval" value="1000"></property>
		<property name="calendarName" value="tradeTimeAMCalendar"></property>
	</bean>
	<!-- 配置下午监控上交所的任务触发器。 -->
	<bean id="monitorShow2003PMTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		<property name="jobDetail" ref="monitorShow2003JobDetail" />
		<!-- 每隔一秒钟(1000毫秒)执行一次 -->
		<property name="repeatInterval" value="1000"></property>
		<property name="calendarName" value="tradeTimePMCalendar"></property>
	</bean>

 

Java代码  quartz 节假日quartz 节假日
  1. <!-- 排除周六和周日的日历。 -->  
  2.     <bean id="excludeWeekendsCalendar"   class = "org.quartz.impl.calendar.WeeklyCalendar"  />  
  3.       
  4.     <!-- 排除法定节假日的日历。 -->  
  5.     <bean id="tradeDayCalendar"   class = "com.csc108.quartz.TradeDayCalendar" >  
  6.         <constructor-arg ref="excludeWeekendsCalendar"  />  
  7.         <constructor-arg value="${tradeDays.legalHolidays}"  />  
  8.     </bean>  
  9.   
  10.     <!-- 上午9 : 15 11 : 45 的交易时间 -->  
  11.     <bean id="tradeTimeAMCalendar"   class = "org.quartz.impl.calendar.DailyCalendar" >  
  12.         <constructor-arg ref="tradeDayCalendar"  />  
  13.         <constructor-arg value="09:15"  type= "java.lang.String"  />  
  14.         <constructor-arg value="11:45"  type= "java.lang.String"  />  
  15.         <!-- include hours between start and end -->  
  16.         <property name="invertTimeRange"  value= "true"  />  
  17.     </bean>  
  18.   
  19.     <!-- 下午12 : 40 15 : 25 的交易时间 -->  
  20.     <bean id="tradeTimePMCalendar"   class = "org.quartz.impl.calendar.DailyCalendar" >  
  21.         <constructor-arg ref="tradeDayCalendar"  />  
  22.         <constructor-arg value="12:45"  type= "java.lang.String"  />  
  23.         <constructor-arg value="15:25"  type= "java.lang.String"  />  
  24.         <!-- include hours between start and end -->  
  25.         <property name="invertTimeRange"  value= "true"  />  
  26.     </bean>  
<!-- 排除周六和周日的日历。 -->
	<bean id="excludeWeekendsCalendar" class="org.quartz.impl.calendar.WeeklyCalendar" />
	
	<!-- 排除法定节假日的日历。 -->
	<bean id="tradeDayCalendar" class="com.csc108.quartz.TradeDayCalendar">
		<constructor-arg ref="excludeWeekendsCalendar" />
		<constructor-arg value="${tradeDays.legalHolidays}" />
	</bean>

	<!-- 上午9:15到11:45的交易时间 -->
	<bean id="tradeTimeAMCalendar" class="org.quartz.impl.calendar.DailyCalendar">
		<constructor-arg ref="tradeDayCalendar" />
		<constructor-arg value="09:15" type="java.lang.String" />
		<constructor-arg value="11:45" type="java.lang.String" />
		<!-- include hours between start and end -->
		<property name="invertTimeRange" value="true" />
	</bean>

	<!-- 下午12:40到15:25的交易时间 -->
	<bean id="tradeTimePMCalendar" class="org.quartz.impl.calendar.DailyCalendar">
		<constructor-arg ref="tradeDayCalendar" />
		<constructor-arg value="12:45" type="java.lang.String" />
		<constructor-arg value="15:25" type="java.lang.String" />
		<!-- include hours between start and end -->
		<property name="invertTimeRange" value="true" />
	</bean>

 

Java代码  quartz 节假日quartz 节假日
  1. <!-- 上午和下午交易时间监控上交股票行情信息的任务调度。 -->  
  2.     <bean id="schedulerFactoryBean"   
        class = "org.springframework.scheduling.quartz.SchedulerFactoryBean" >           <property name="calendars" >               <map>                   <entry key="tradeTimeAMCalendar"  value-ref= "tradeTimeAMCalendar" />                   <entry key="tradeTimePMCalendar"  value-ref= "tradeTimePMCalendar" />               </map>           </property>           <property name="triggers" >               <list>                   <ref bean="monitorShow2003AMTrigger" />                   <ref bean="monitorShow2003PMTrigger"  />               </list>           </property>       </bean> 

上一篇: Vue 指令directives

下一篇: es742&ka742