📄 nthincludeddaytrigger.java
字号:
/*
* Copyright 2004-2005 OpenSymphony
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
package org.quartz;
import java.text.NumberFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* A trigger which fires on the N<SUP>th</SUP> day of every interval type
* ({@link #INTERVAL_TYPE_WEEKLY}, {@link #INTERVAL_TYPE_MONTHLY} or
* {@link #INTERVAL_TYPE_YEARLY}) that is <i>not</i> excluded by the associated
* calendar. When determining what the N<SUP>th</SUP> day of the month or year
* is, <CODE>NthIncludedDayTrigger</CODE> will skip excluded days on the
* associated calendar. This would commonly be used in an N<SUP>th</SUP>
* business day situation, in which the user wishes to fire a particular job on
* the N<SUP>th</SUP> business day (i.e. the 5<SUP>th</SUP> business day of
* every month). Each <CODE>NthIncludedDayTrigger</CODE> also has an associated
* <CODE>fireAtTime</CODE> which indicates at what time of day the trigger is
* to fire.
* <P>
* All <CODE>NthIncludedDayTrigger</CODE>s default to a monthly interval type
* (fires on the N<SUP>th</SUP> day of every month) with N = 1 (first
* non-excluded day) and <CODE>fireAtTime</CODE> set to 12:00 PM (noon). These
* values can be changed using the {@link #setN}, {@link #setIntervalType}, and
* {@link #setFireAtTime} methods. Users may also want to note the
* {@link #setNextFireCutoffInterval} and {@link #getNextFireCutoffInterval}
* methods.
* <P>
* Take, for example, the following calendar:
* <P>
* <PRE>
* July August September
* Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
* 1 W 1 2 3 4 5 W 1 2 W
* W H 5 6 7 8 W W 8 9 10 11 12 W W H 6 7 8 9 W
* W 11 12 13 14 15 W W 15 16 17 18 19 W W 12 13 14 15 16 W
* W 18 19 20 21 22 W W 22 23 24 25 26 W W 19 20 21 22 23 W
* W 25 26 27 28 29 W W 29 30 31 W 26 27 28 29 30
* W
* </PRE>
* <P>
* Where W's represent weekend days, and H's represent holidays, all of which
* are excluded on a calendar associated with an
* <CODE>NthIncludedDayTrigger</CODE> with <CODE>n=5</CODE> and
* <CODE>intervalType=INTERVAL_TYPE_MONTHLY</CODE>. In this case, the trigger
* would fire on the 8<SUP>th</SUP> of July (because of the July 4 holiday),
* the 5<SUP>th</SUP> of August, and the 8<SUP>th</SUP> of September (because
* of Labor Day).
*
* @author Aaron Craven
*/
public class NthIncludedDayTrigger extends Trigger {
static final long serialVersionUID = 6267700049629328293L;
/**
* Instructs the <CODE>Scheduler</CODE> that upon a mis-fire situation, the
* <CODE>NthIncludedDayTrigger</CODE> wants to be fired now by the
* <CODE>Scheduler</CODE>
*/
public static final int MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1;
/**
* Instructs the <CODE>Scheduler</CODE> that upon a mis-fire situation, the
* <CODE>NthIncludedDayTrigger</CODE> wants to have
* <CODE>nextFireTime</CODE> updated to the next time in the schedule after
* the current time, but it does not want to be fired now.
*/
public static final int MISFIRE_INSTRUCTION_DO_NOTHING = 2;
/**
* indicates a monthly trigger type (fires on the N<SUP>th</SUP> included
* day of every month).
*/
public static final int INTERVAL_TYPE_MONTHLY = 1;
/**
* indicates a yearly trigger type (fires on the N<SUP>th</SUP> included
* day of every year).
*/
public static final int INTERVAL_TYPE_YEARLY = 2;
/**
* indicates a weekly trigger type (fires on the N<SUP>th</SUP> included
* day of every week). When using this interval type, care must be taken
* not to think of the value of <CODE>n</CODE> as an analog to
* <CODE>java.util.Calendar.DAY_OF_WEEK</CODE>. Such a comparison can only
* be drawn when there are no calendars associated with the trigger. To
* illustrate, consider an <CODE>NthIncludedDayTrigger</CODE> with
* <CODE>n = 3</CODE> which is associated with a Calendar excluding
* non-weekdays. The trigger would fire on the 3<SUP>rd</SUP>
* <I>included</I> day of the week, which would be 4<SUP>th</SUP>
* <I>actual</I> day of the week.
*/
public static final int INTERVAL_TYPE_WEEKLY = 3;
private Date startTime = new Date();
private Date endTime;
private Date previousFireTime;
private Date nextFireTime;
private Calendar calendar;
private int n = 1;
private int intervalType = INTERVAL_TYPE_MONTHLY;
private int fireAtHour = 12;
private int fireAtMinute = 0;
private int fireAtSecond = 0;
private int nextFireCutoffInterval = 12;
private TimeZone timeZone;
/**
* Create an <CODE>NthIncludedDayTrigger</CODE> with no specified name,
* group, or <CODE>JobDetail</CODE>. This will result initially in a
* default monthly trigger that fires on the first day of every month at
* 12:00 PM (<CODE>n</CODE>=1,
* <CODE>intervalType={@link #INTERVAL_TYPE_MONTHLY}</CODE>,
* <CODE>fireAtTime="12:00"</CODE>).
* <P>
* Note that <CODE>setName()</CODE>, <CODE>setGroup()</CODE>,
* <CODE>setJobName()</CODE>, and <CODE>setJobGroup()</CODE>, must be
* called before the <CODE>NthIncludedDayTrigger</CODE> can be placed into
* a <CODE>Scheduler</CODE>.
*/
public NthIncludedDayTrigger() {
super();
}
/**
* Create an <CODE>NthIncludedDayTrigger</CODE> with the given name and
* group but no specified <CODE>JobDetail</CODE>. This will result
* initially in a default monthly trigger that fires on the first day of
* every month at 12:00 PM (<CODE>n</CODE>=1,
* <CODE>intervalType={@link #INTERVAL_TYPE_MONTHLY}</CODE>,
* <CODE>fireAtTime="12:00"</CODE>).
* <P>
* Note that <CODE>setJobName()</CODE> and <CODE>setJobGroup()</CODE> must
* be called before the <CODE>NthIncludedDayTrigger</CODE> can be placed
* into a <CODE>Scheduler</CODE>.
*
* @param name the name for the <CODE>NthIncludedDayTrigger</CODE>
* @param group the group for the <CODE>NthIncludedDayTrigger</CODE>
*/
public NthIncludedDayTrigger(String name, String group) {
super(name, group);
}
/**
* Create an <CODE>NthIncludedDayTrigger</CODE> with the given name and
* group and the specified <CODE>JobDetail</CODE>. This will result
* initially in a default monthly trigger that fires on the first day of
* every month at 12:00 PM (<CODE>n</CODE>=1,
* <CODE>intervalType={@link #INTERVAL_TYPE_MONTHLY}</CODE>,
* <CODE>fireAtTime="12:00"</CODE>).
*
* @param name the name for the <CODE>NthIncludedDayTrigger</CODE>
* @param group the group for the <CODE>NthIncludedDayTrigger</CODE>
* @param jobName the name of the job to associate with the
* <CODE>NthIncludedDayTrigger</CODE>
* @param jobGroup the group containing the job to associate with the
* <CODE>NthIncludedDayTrigger</CODE>
*/
public NthIncludedDayTrigger(String name, String group, String jobName,
String jobGroup) {
super(name, group, jobName, jobGroup);
}
/**
* Sets the day of the interval on which the
* <CODE>NthIncludedDayTrigger</CODE> should fire. If the N<SUP>th</SUP>
* day of the interval does not exist (i.e. the 32<SUP>nd</SUP> of a
* month), the trigger simply will never fire. N may not be less than 1.
*
* @param n the day of the interval on which the trigger should fire.
* @throws java.lang.IllegalArgumentException
* the value entered for N was not valid (probably less than or
* equal to zero).
* @see #getN()
*/
public void setN(int n) {
if (n > 0) {
this.n = n;
} else {
throw new IllegalArgumentException("N must be greater than 0.");
}
}
/**
* Returns the day of the interval on which the
* <CODE>NthIncludedDayTrigger</CODE> should fire.
*
* @return the value of <CODE>n</CODE>
* @see #setN(int)
*/
public int getN() {
return this.n;
}
/**
* Sets the interval type for the <CODE>NthIncludedDayTrigger</CODE>. If
* {@link #INTERVAL_TYPE_MONTHLY}, the trigger will fire on the
* N<SUP>th</SUP> included day of every month. If
* {@link #INTERVAL_TYPE_YEARLY}, the trigger will fire on the
* N<SUP>th</SUP> included day of every year. If
* {@link #INTERVAL_TYPE_WEEKLY}, the trigger will fire on the
* N<SUP>th</SUP> included day of every week.
*
* @param intervalType the interval type for the trigger
* @throws java.lang.IllegalArgumentException
* the value of <CODE>intervalType</CODE> is not valid. Valid
* values are represented by the INTERVAL_TYPE_WEEKLY,
* INTERVAL_TYPE_MONTHLY and INTERVAL_TYPE_YEARLY constants.
* @see #getIntervalType()
* @see #INTERVAL_TYPE_WEEKLY
* @see #INTERVAL_TYPE_MONTHLY
* @see #INTERVAL_TYPE_YEARLY
*/
public void setIntervalType(int intervalType) {
switch (intervalType) {
case INTERVAL_TYPE_WEEKLY:
this.intervalType = intervalType;
break;
case INTERVAL_TYPE_MONTHLY:
this.intervalType = intervalType;
break;
case INTERVAL_TYPE_YEARLY:
this.intervalType = intervalType;
break;
default:
throw new IllegalArgumentException("Invalid Interval Type:"
+ intervalType);
}
}
/**
* Returns the interval type for the <CODE>NthIncludedDayTrigger</CODE>.
*
* @return the trigger's interval type
* @see #setIntervalType(int)
* @see #INTERVAL_TYPE_WEEKLY
* @see #INTERVAL_TYPE_MONTHLY
* @see #INTERVAL_TYPE_YEARLY
*/
public int getIntervalType() {
return this.intervalType;
}
/**
* Sets the fire time for the <CODE>NthIncludedDayTrigger</CODE>, which
* should be represented as a string with the format
* "HH:MM[:SS]", with HH representing the 24-hour clock hour
* of the fire time. Hours can be represented as either a one-digit or
* two-digit number. Seconds are optional.
*
* @param fireAtTime the time at which the trigger should fire
* @throws java.lang.IllegalArgumentException
* the specified value for <CODE>fireAtTime</CODE> could not be
* successfully parsed into a valid time of day.
* @see #getFireAtTime()
*/
public void setFireAtTime(String fireAtTime) {
int newFireHour;
int newFireMinute;
int newFireSecond = 0;
try {
int i = fireAtTime.indexOf(":");
newFireHour = Integer.parseInt(fireAtTime.substring(0, i));
newFireMinute = Integer.parseInt(fireAtTime.substring(i+1, i+3));
i = fireAtTime.indexOf(":", i+1);
if (i > -1) {
newFireSecond = Integer.parseInt(fireAtTime.substring(i+1));
}
} catch (Exception e) {
throw new IllegalArgumentException(
"Could not parse time expression '" + fireAtTime + "':" + e.getMessage());
}
// Check ranges
if ((newFireHour < 0) || (newFireHour > 23)) {
throw new IllegalArgumentException(
"Could not parse time expression '" + fireAtTime + "':" +
"fireAtHour must be between 0 and 23");
} else if ((newFireMinute < 0) || (newFireMinute > 59)) {
throw new IllegalArgumentException(
"Could not parse time expression '" + fireAtTime + "':" +
"fireAtMinute must be between 0 and 59");
} else if ((newFireSecond < 0) || (newFireSecond > 59)) {
throw new IllegalArgumentException(
"Could not parse time expression '" + fireAtTime + "':" +
"fireAtMinute must be between 0 and 59");
}
fireAtHour = newFireHour;
fireAtMinute = newFireMinute;
fireAtSecond = newFireSecond;
}
/**
* Returns the fire time for the <CODE>NthIncludedDayTrigger</CODE> as a
* string with the format "HH:MM[:SS]", with HH representing the
* 24-hour clock hour of the fire time. Seconds are optional and their
* inclusion depends on whether or not they were provided to
* {@link #setFireAtTime(String)}.
*
* @return the fire time for the trigger
* @see #setFireAtTime(String)
*/
public String getFireAtTime() {
NumberFormat format = NumberFormat.getNumberInstance();
format.setMaximumIntegerDigits(2);
format.setMinimumIntegerDigits(2);
format.setMaximumFractionDigits(0);
return format.format(this.fireAtHour) + ":" +
format.format(this.fireAtMinute) + ":" +
format.format(this.fireAtSecond);
}
/**
* Sets the <CODE>nextFireCutoffInterval</CODE> for the
* <CODE>NthIncludedDayTrigger</CODE>.
* <P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -