⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nthincludeddaytrigger.java

📁 Quartz is a full-featured, open source job scheduling system that can be integrated with, or used al
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* 
 * 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 
     * &quot;HH:MM[:SS]&quot;, 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 &quot;HH:MM[:SS]&quot;, 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 + -