Class CronTrigger

  • All Implemented Interfaces:
    Trigger, ZonedTrigger

    public class CronTrigger
    extends java.lang.Object
    implements ZonedTrigger

    Cron-based Trigger implementation, which supports 5 or 6 fields delimited by a single space character, plus a ZoneId. Basic cron syntax is supported. For more advanced scenarios, you can subclass this implementation or combine multiple CronTrigger instances in a Trigger implementation of your own.

    Cron Expression Fields
    seconds (optional)0-59, *. When absent, 0 is assumed
    minutes0-59, *
    hours0-23, *
    dayOfMonth0-31, *, L
    month1-12, JAN-DEC, January-December, *
    dayOfWeekSUN-SAT, Sunday-Saturday, 0-7, *. 0 and 7 both represent Sunday: 0 to designate the first day of the week, and 7 for consistency with DayOfWeek.

    Cron Expression Syntax
    , delimits lists for all fields. For example, MON,WED,FRI or MAY,SEP
    - delimits ranges for all fields. For example, MON-FRI or 9-17
    / specifies a repeating increment for all fields except dayOfWeek. For example, 6/7 for the hours field equates to 6,13,20.
    # specifies an ordinal day of week. For example, FRI#1,SAT#L is the first Friday and last Saturday of the month.
    # cannot be used within ranges (-) and increments (/).
    * indicates any value is permitted.
    L indicates the last day of the month. 2L indicates the second-to-last day, and so forth.

    Cron Expression Examples
    0 * * * * every hour at the top of the hour
    0 9-17 * * MON-FRI weekdays from 9am to 5pm, at the top of each hour
    0 13/3 * MAY-SEP SAT,SUN weekends from May to September, every 3 hours, starting at 1pm
    30 10 * APR,AUG TUE#2,TUE#L second and last Tuesdays of April and August at 10:30am
    15 22 4 10,20,L * * 4:22:15 AM on the 10th, 20th, and last day of every month
    0 8-11,13-16 2L JAN-MAR * 8AM-11AM and 1PM-4PM on the second-to-last day of January, February, and March

    A constructor is provided that accepts a cron expression such as the above and a timezone id. For example,

     trigger = new CronTrigger("0 7 * SEP-MAY MON-FRI", ZoneId.of("America/New_York"));
     

    Another constructor allows cron fields to be specified in a fluent manner, in any order. For example,

     trigger = new CronTrigger(ZoneId.of("America/Los_Angeles"))
               .months(Month.DECEMBER)
               .daysOfMonth(24)
               .hours(16, 18);
     

    The getNextRunTime method of this trigger determines the next run time based on the cron schedule. The skipRun method always returns false unless overridden by a subclass.

    Methods of this class that configure the cron expression fields are not thread safe. It is the responsibility of the caller to ensure that initialization of the CronTrigger happens before it is supplied to a ManagedScheduledExecutorService and that the CronTrigger is not subsequently modified.

    You can subclass CronTrigger to provide for more complex logic, such as in the following example of combining two triggers to schedule twice-a-month payroll on the 15th and last day of month or the prior Fridays when the former fall on a weekend:

     public class PayrollTrigger extends CronTrigger {
         private final CronTrigger fridaysBeforeWeekendPayrollDay;
    
         PayrollTrigger() {
             // Every 15th and last day of the month that is a weekday,
             super("0 10 15,L * MON-FRI", ZoneId.of("America/Chicago"));
    
             // Every 13th, 14th, third-to-last, and second-to-last day of the month that is a Friday,
             fridaysBeforeWeekendPayrollDay = new CronTrigger(
                     "0 10 13,14,3L,2L * FRI", getZoneId());
         }
    
         public ZonedDateTime getNextRunTime(LastExecution lastExec, ZonedDateTime scheduledAt) {
             ZonedDateTime time1 = super.getNextRunTime(lastExec, scheduledAt);
             ZonedDateTime time2 = fridaysBeforeWeekendPayrollDay.getNextRunTime(lastExec, scheduledAt);
             return time1.isBefore(time2) ? time1 : time2;
         }
     }
     
    Since:
    3.0
    • Constructor Summary

      Constructors 
      Constructor Description
      CronTrigger​(java.lang.String cron, java.time.ZoneId zone)
      Constructor that accepts a cron expression.
      CronTrigger​(java.time.ZoneId zone)
      Constructor for the fluent configuration pattern.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private static void add​(java.util.SortedSet<java.lang.Integer> vals, int start, int end, int increment)  
      CronTrigger daysOfMonth​(int... d)
      Configure the day-of-month cron field, overwriting any previous value for day-of-month.
      CronTrigger daysOfMonth​(java.lang.String d)
      Configure the day-of-month cron field, overwriting any previous value for day-of-month.
      CronTrigger daysOfWeek​(java.lang.String d)
      Configure the day-of-week cron field, overwriting any previous value for day-of-week.
      CronTrigger daysOfWeek​(java.time.DayOfWeek... d)
      Configure the day-of-week cron field, overwriting any previous value for day-of-week.
      java.time.ZonedDateTime getNextRunTime​(LastExecution lastExecutionInfo, java.time.ZonedDateTime taskScheduledTime)
      Using the cron schedule, and based on the end of the most recent execution (or absent that, the initial scheduling time), retrieve the next time that the task should run after.
      java.time.ZoneId getZoneId()
      Returns the timezone to use for ZonedDateTime that is supplied to the getNextRunTime and skipRun methods.
      CronTrigger hours​(int... h)
      Configure the hours cron field, overwriting any previous value for hours.
      CronTrigger hours​(java.lang.String h)
      Configure the hours cron field, overwriting any previous value for hours.
      CronTrigger minutes​(int... m)
      Configure the minutes cron field, overwriting any previous value for minutes.
      CronTrigger minutes​(java.lang.String m)
      Configure the minutes cron field, overwriting any previous value for minutes.
      CronTrigger months​(java.lang.String m)
      Configure the months cron field, overwriting any previous value for months.
      CronTrigger months​(java.time.Month... m)
      Configure the month cron field, overwriting any previous value for month.
      protected java.time.ZonedDateTime next​(java.time.ZonedDateTime from)
      Advance to the next date/time according to the cron schedule.
      private java.time.ZonedDateTime nextDayOfMonth​(int dayIndex, int lastDayIndex, int monthIndex, int year, java.time.ZonedDateTime time)
      Advance to next day of month.
      private java.time.ZonedDateTime nextHour​(int hourIndex, int dayIndex, int lastDayIndex, int dayOfMonth, int monthIndex, int year, java.time.ZonedDateTime time)
      Advance to next hour.
      private java.time.ZonedDateTime nextMinute​(int minuteIndex, int hourIndex, int dayIndex, int lastDayIndex, int dayOfMonth, int monthIndex, int year, java.time.ZonedDateTime time)
      Advance to next minute.
      private java.time.ZonedDateTime nextMonth​(int month, int year)
      Advance to next month.
      private java.time.ZonedDateTime nextSecond​(int secondIndex, int minuteIndex, int hourIndex, int dayIndex, int lastDayIndex, int dayOfMonth, int monthIndex, int year, java.time.ZonedDateTime time)
      Advance to next second.
      private int[] parse​(java.lang.String type, int min, int max, int[] list)
      Validate that the supplied list values are within the allowed range for the cron field type.
      private int[] parse​(java.lang.String name, int min, int max, int maxExt, java.lang.String field, java.util.function.Function<java.lang.String,​java.lang.Integer> parser)
      Validate that the supplied list values are within the allowed range for the cron field type.
      private static int parseDayOfMonth​(java.lang.String day)
      Convert dayOfMonth value to 1-31, or negative for days from the end of the month For example, L is the last day (-1) and 2L is the second to last day (-2).
      private static int parseDayOfWeek​(java.lang.String dayName)
      Convert dayOfWeek value to 1-49 where first 7 are standard week days, next 35 are ordinal 1st-5th of each day, and final 7 are ordinal last for each day.
      private static int parseMonth​(java.lang.String monthName)
      Convert month value to 1-12.
      CronTrigger seconds​(int... s)
      Configure the seconds cron field, overwriting any previous value for seconds.
      CronTrigger seconds​(java.lang.String s)
      Configure the seconds cron field, overwriting any previous value for seconds.
      java.lang.String toString()
      Readable representation of the CronTrigger, which displays fields in list form or with the * character for brevity.
      private void toStringBuilder​(java.lang.StringBuilder s, java.lang.String label, int[] list, int max)
      Utility method for repeated logic in toString.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • DAYS_OF_WEEK

        private static final java.util.Map<java.lang.String,​java.lang.Integer> DAYS_OF_WEEK
      • MONTHS

        private static final java.util.Map<java.lang.String,​java.lang.Integer> MONTHS
      • ALL_DAYS_OF_MONTH

        private static final int[] ALL_DAYS_OF_MONTH
      • ALL_DAYS_OF_WEEK

        private static final int[] ALL_DAYS_OF_WEEK
      • ALL_MONTHS

        private static final int[] ALL_MONTHS
      • ZERO

        private static final int[] ZERO
      • daysOfMonth

        private int[] daysOfMonth
      • daysOfWeek

        private int[] daysOfWeek
      • hours

        private int[] hours
      • minutes

        private int[] minutes
      • months

        private int[] months
      • seconds

        private int[] seconds
      • zone

        private final java.time.ZoneId zone
    • Constructor Detail

      • CronTrigger

        public CronTrigger​(java.lang.String cron,
                           java.time.ZoneId zone)
        Constructor that accepts a cron expression.
        Parameters:
        cron - cron expression.
        zone - timezone ID to use for ZonedDateTime that is supplied to getNextRunTime and skipRun methods. Null indicates to use the system default.
      • CronTrigger

        public CronTrigger​(java.time.ZoneId zone)
        Constructor for the fluent configuration pattern. Seconds, minutes, and hours default to 0. The remaining fields default to *.
        Parameters:
        zone - timezone ID to use for ZonedDateTime that is supplied to getNextRunTime and skipRun methods. Null indicates to use the system default.
    • Method Detail

      • getNextRunTime

        public java.time.ZonedDateTime getNextRunTime​(LastExecution lastExecutionInfo,
                                                      java.time.ZonedDateTime taskScheduledTime)
        Using the cron schedule, and based on the end of the most recent execution (or absent that, the initial scheduling time), retrieve the next time that the task should run after.
        Specified by:
        getNextRunTime in interface ZonedTrigger
        Parameters:
        lastExecutionInfo - information about the last execution of the task. This value will be null if the task has not yet run.
        taskScheduledTime - the date/time at which the ManagedScheduledExecutorService.schedule method was invoked to schedule the task.
        Returns:
        the date/time after which the next execution of the task should start.
        Throws:
        java.time.DateTimeException - if a next time cannot be determined from the cron expression.
      • getZoneId

        public final java.time.ZoneId getZoneId()
        Returns the timezone to use for ZonedDateTime that is supplied to the getNextRunTime and skipRun methods.
        Specified by:
        getZoneId in interface ZonedTrigger
        Returns:
        timezone to use for operations on this trigger.
      • daysOfMonth

        public CronTrigger daysOfMonth​(int... d)
        Configure the day-of-month cron field, overwriting any previous value for day-of-month.
        Parameters:
        d - one or more day numbers ranging from 1 to 31.
        Returns:
        this instance.
      • daysOfMonth

        public CronTrigger daysOfMonth​(java.lang.String d)
        Configure the day-of-month cron field, overwriting any previous value for day-of-month.
        Parameters:
        d - dayOfMonth cron field. For example, 15,L.
        Returns:
        this instance.
      • daysOfWeek

        public CronTrigger daysOfWeek​(java.time.DayOfWeek... d)
        Configure the day-of-week cron field, overwriting any previous value for day-of-week.
        Parameters:
        d - one or more days of the week.
        Returns:
        this instance.
      • daysOfWeek

        public CronTrigger daysOfWeek​(java.lang.String d)
        Configure the day-of-week cron field, overwriting any previous value for day-of-week.
        Parameters:
        d - dayOfWeek cron field. For example, MON-FRI,SAT#L.
        Returns:
        this instance.
      • hours

        public CronTrigger hours​(int... h)
        Configure the hours cron field, overwriting any previous value for hours.
        Parameters:
        h - one or more hour values ranging from 0 to 23.
        Returns:
        this instance.
      • hours

        public CronTrigger hours​(java.lang.String h)
        Configure the hours cron field, overwriting any previous value for hours.
        Parameters:
        h - hours cron field. For example, 9-17 for 9am to 5pm.
        Returns:
        this instance.
      • minutes

        public CronTrigger minutes​(int... m)
        Configure the minutes cron field, overwriting any previous value for minutes.
        Parameters:
        m - one or more minute values ranging from 0 to 59.
        Returns:
        this instance.
      • minutes

        public CronTrigger minutes​(java.lang.String m)
        Configure the minutes cron field, overwriting any previous value for minutes.
        Parameters:
        m - minutes cron field. For example, 5/10 for 10 minute intervals starting at 5 minutes after the hour (:05, :15, :25, :35, :45, :55).
        Returns:
        this instance.
      • months

        public CronTrigger months​(java.time.Month... m)
        Configure the month cron field, overwriting any previous value for month.
        Parameters:
        m - one or more months.
        Returns:
        this instance.
      • months

        public CronTrigger months​(java.lang.String m)
        Configure the months cron field, overwriting any previous value for months.
        Parameters:
        m - months cron field. For example, SEP-NOV,FEB-MAY.
        Returns:
        this instance.
      • seconds

        public CronTrigger seconds​(int... s)
        Configure the seconds cron field, overwriting any previous value for seconds.
        Parameters:
        s - one or more seconds values ranging from 0 to 59.
        Returns:
        this instance.
      • seconds

        public CronTrigger seconds​(java.lang.String s)
        Configure the seconds cron field, overwriting any previous value for seconds.
        Parameters:
        s - seconds cron field. For example, 30.
        Returns:
        this instance.
      • toString

        public java.lang.String toString()
        Readable representation of the CronTrigger, which displays fields in list form or with the * character for brevity.

        For example,

        CronTrigger@89abcdef seconds 0, minutes 0, hours 9, *, months 3,6,9,12, SAT#2,SAT#4
        Overrides:
        toString in class java.lang.Object
        Returns:
        readable representation of the parsed cron expression.
      • toStringBuilder

        private void toStringBuilder​(java.lang.StringBuilder s,
                                     java.lang.String label,
                                     int[] list,
                                     int max)
        Utility method for repeated logic in toString.
        Parameters:
        s - The string builder
        label - The cron expression
        list - Cron expression as list
        max - Max value of cron expression
      • next

        protected java.time.ZonedDateTime next​(java.time.ZonedDateTime from)
        Advance to the next date/time according to the cron schedule.
        Parameters:
        from - the date/time from which to compute the next time.
        Returns:
        next date/time according to the cron schedule, or the original time if it matches.
      • nextDayOfMonth

        private java.time.ZonedDateTime nextDayOfMonth​(int dayIndex,
                                                       int lastDayIndex,
                                                       int monthIndex,
                                                       int year,
                                                       java.time.ZonedDateTime time)
        Advance to next day of month.
        Parameters:
        dayIndex - index of the day in daysOfMonth[]
        lastDayIndex - index of the last day of the month in daysOfMonth[]
        monthIndex - index of the month in months[]
        year - year
        time - Date/Time
        Returns:
        ZonedDateTime for next month
      • nextHour

        private java.time.ZonedDateTime nextHour​(int hourIndex,
                                                 int dayIndex,
                                                 int lastDayIndex,
                                                 int dayOfMonth,
                                                 int monthIndex,
                                                 int year,
                                                 java.time.ZonedDateTime time)
        Advance to next hour.
        Parameters:
        hourIndex - index of the hour in hours[]
        dayIndex - index of the day in daysOfMonth[]
        lastDayIndex - index of the last day of the month in daysOfMonth[]
        dayOfMonth - day of month
        monthIndex - index of the month in months[]
        year - year
        time - Date/Time
        Returns:
        ZonedDateTime for next hour
      • nextMinute

        private java.time.ZonedDateTime nextMinute​(int minuteIndex,
                                                   int hourIndex,
                                                   int dayIndex,
                                                   int lastDayIndex,
                                                   int dayOfMonth,
                                                   int monthIndex,
                                                   int year,
                                                   java.time.ZonedDateTime time)
        Advance to next minute.
        Parameters:
        minuteIndex - index of the minute in minutes[]
        hourIndex - index of the hour in hours[]
        dayIndex - index of the day in daysOfMonth[]
        lastDayIndex - index of the last day of the month in daysOfMonth[]
        dayOfMonth - day of month
        monthIndex - index of the month in months[]
        year - year
        time - Date/Time
        Returns:
        ZonedDateTime for next second
      • nextMonth

        private java.time.ZonedDateTime nextMonth​(int month,
                                                  int year)
        Advance to next month.
        Parameters:
        month - the month
        year - the year
        Returns:
        ZonedDateTime for next month
      • nextSecond

        private java.time.ZonedDateTime nextSecond​(int secondIndex,
                                                   int minuteIndex,
                                                   int hourIndex,
                                                   int dayIndex,
                                                   int lastDayIndex,
                                                   int dayOfMonth,
                                                   int monthIndex,
                                                   int year,
                                                   java.time.ZonedDateTime time)
        Advance to next second.
        Parameters:
        secondIndex - index of the second in seconds[]
        minuteIndex - index of the minute in minutes[]
        hourIndex - index of the hour in hours[]
        dayIndex - index of the day in daysOfMonth[]
        lastDayIndex - index of the last day of the month in daysOfMonth[]
        dayOfMonth - day of month
        monthIndex - index of the month in months[]
        year - year
        time - Date/Time
        Returns:
        ZonedDateTime for next second
      • add

        private static final void add​(java.util.SortedSet<java.lang.Integer> vals,
                                      int start,
                                      int end,
                                      int increment)
      • parse

        private int[] parse​(java.lang.String type,
                            int min,
                            int max,
                            int[] list)
        Validate that the supplied list values are within the allowed range for the cron field type.
        Parameters:
        type - cron field type, such as months or hours.
        min - minimum allowed value
        max - maximum allowed value
        list - supplied list of values
        Returns:
        sorted list of values with any duplicates removed.
      • parse

        private int[] parse​(java.lang.String name,
                            int min,
                            int max,
                            int maxExt,
                            java.lang.String field,
                            java.util.function.Function<java.lang.String,​java.lang.Integer> parser)
        Validate that the supplied list values are within the allowed range for the cron field type.
        Parameters:
        name - cron field type, such as months or hours.
        min - minimum allowed normal value
        max - maximum allowed normal value
        maxExt - maximum allowed special value (L or SUN#L), or max if no special values allowed for this field.
        field - the field's cron expression
        parser - parser function, such as Integer::parseInt or CronTrigger::parseMonth
        Returns:
        sorted list of values with any duplicates removed.
      • parseDayOfMonth

        private static int parseDayOfMonth​(java.lang.String day)
                                    throws java.lang.IllegalArgumentException
        Convert dayOfMonth value to 1-31, or negative for days from the end of the month For example, L is the last day (-1) and 2L is the second to last day (-2).
        Parameters:
        day - name of day of month
        Returns:
        integer representation of day of month
        Throws:
        java.lang.IllegalArgumentException
      • parseDayOfWeek

        private static int parseDayOfWeek​(java.lang.String dayName)
                                   throws java.lang.IllegalArgumentException
        Convert dayOfWeek value to 1-49 where first 7 are standard week days, next 35 are ordinal 1st-5th of each day, and final 7 are ordinal last for each day.
        Parameters:
        dayName - name of day of the week
        Returns:
        integer representation of day of week
        Throws:
        java.lang.IllegalArgumentException
      • parseMonth

        private static int parseMonth​(java.lang.String monthName)
                               throws java.lang.IllegalArgumentException
        Convert month value to 1-12.
        Parameters:
        monthName - name of month (January)
        Returns:
        integer representation of month
        Throws:
        java.lang.IllegalArgumentException