Child pages
  • Time Expressions

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

If you don't want to use the string Cron syntax directly, you can use the Cron helper object to generate your Cron expression. The Cron object API can generate any legal Cron expression. It doesn't matter whether you prefer to write out your Cron expressions using strings or whether you use the Cron API. At runtime, it's all the same.

Using the Cron Helper Object to Create For-Loops

The above section describes how to create a for-loop. This section describes how to create that same for-loop using a Cron helper object.

The end result of using the Cron helper object is exactly the same as if you had generated the Cron time expression yourself. The only difference is how the Cron time expression string is generated.

The code that uses the Cron helper object to generate a Cron time expression as described above can be found below. For reference, the code below will generate a Cron time expression that is equivalent, but not necessarily identical, to the following Cron time expression.

Panel
0 0 (15 10; 30 12; */15 *) * * *

The code below first uses a Cron helper object. EngineHelper is a factory for flux.Cron objects.

Next, we need to create the "start", "end", and "increment" constraints of the for-loop. These three constraints represent the three components inside the parentheses in the above for-loop Cron expression.

Finally, we put the three constraints together to form the for-loop and finish off the Cron object.

If you call toString() on the final Cron object, the returned string will look different than the above Cron expression. However, the semantics are identical.

To use the Cron expression created by this Cron object, call Cron.toString().// Generate a Cron time expression equivalent to:

Panel
// 0 0 (15 10; 30 12; */15 *) * * *
Code Block
languagejava
    Factory factory = Factory.makeInstance();

// Make the start constraint.
    CronSlice startConstraint =
        EngineHelper.makeCronSlice(CronColumn.MINUTE, CronColumn.HOUR);
    startConstraint.add(CronColumn.MINUTE, 15);
    startConstraint.add(CronColumn.HOUR, 10);

// Make the end constraint.
    CronSlice endConstraint =
        EngineHelper.makeCronSlice(CronColumn.MINUTE, CronColumn.HOUR);
    endConstraint.add(CronColumn.MINUTE, 30);
    endConstraint.add(CronColumn.HOUR, 12);

// Make the increment constraint.
    CronSlice incrementConstraint =
        EngineHelper.makeCronSlice(CronColumn.MINUTE, CronColumn.HOUR);
    incrementConstraint.add(CronColumn.MINUTE, "*/15");
    incrementConstraint.add(CronColumn.HOUR, "*");

// Create the for-loop.
    CronSlice forLoop = EngineHelper.makeCronForLoop(startConstraint, endConstraint, incrementConstraint);

// Finish off the Cron object.
    Cron finalCron = EngineHelper.makeCron(forLoop);
    finalCron.add(CronColumn.MILLISECOND, 0);
    finalCron.add(CronColumn.SECOND, 0);

// Finally, generate the Cron time expression to be used elsewhere.
// 'finalCron' is equivalent to: 0 0 (15 10; 30 12; */15 *) * * *
    finalCron.toString();

 

Real world time expression examples from our Technical Support Department

Question: How can I schedule a task to fire every 5 minutes between 9:00 and 11:55, Monday through Friday?

Answer: This is an interesting schedule. You can model this need using the "for loop" construct of Cron-style time expressions.

Panel
0 0 (0 9; 55 11; */5 *) * * mon-fri

This Cron-style time expression will fire Monday through Friday, beginning at 9:00 am and firing every 5 minutes until 11:55 am.

Question: How do I schedule a task to fire every 3 weeks on Monday, Tuesday, and Friday, beginning at 10:00, ending at 16:30, and repeating every 5 hours (or 5 minutes)?

Answer: A Cron-style time expression that uses a "for loop" can model this requirement.

Panel
0 0 (0 10; 30 16; 0 +5) * * mon,tue,fri * * +3 *

This Cron-style time expression will fire Monday, Tuesday, and Friday from 10:00 until 16:30 every 5 hours, then skip 3 weeks and repeat.

Note that the "+3" in the week-of-year column allows the task to fire every 3 weeks..

To modify this time expression to fire every 5 minutes instead of every 5 hours, you could change the time expression as follows.

Panel
0 0 (0 10; 30 16; +5 *) * * mon,tue,fri * * +3 *

Notice that the only change is in the "increment constraint" of the "for loop". The constraint "0 +5" (every 5 hours) is changed to "+5 *" (every 5 minutes).

Followup Question: How do I schedule a task to fire every 2 days, beginning at 10:00, ending at 16:30, and repeating every 5 minutes?

Answer: The time expression to use is very similar to the time expressions shown above. Instead of firing on certain days of the week and then skipping 3 weeks, simply fire every 2 days, like so:

Panel
0 0 (0 10; 30 16; +5 *) * * * +2 * * *

The "+2" in the day-of-year column allows this task to fire every 2 days.

Question: How do I define an activity that occurs each month on the last weekday at a particular time (for example, the last Thursday of the month at 18:30, starting 1 January 2002 and ending 31 December 2002).

...

Relative

...

time

...

Answer: Ok, so you want to run a task on the last weekday of the month at 1830. And the period you want to run this in is from 1 January 2002 through 31 December 2002.

First, create a Date object that represents the beginning of the new year in 2003, like so:

Code Block
// New Year's Day 2003, at midnight
Date newYearsDay2003 = EngineHelper.makeDateInDefaultTimeZone("2003 Jan 1 00:00:00.000");

Next, we need a time expression to use that will fire a task on the last weekday of the month at 1830. The following Cron-style time expression expresses this requirement.String timeExpression = "0 0 30 18 $b * *";The above time expression says to fire at 1830 on the last business day of the month. For our purposes, business days are Monday through Friday. You can retrieve a Business Interval that includes Monday through Friday and excludes Saturday and Sunday like so:

Code Block
BusinessIntervalFactory bif = EngineHelper.makeBusinessIntervalFactory();
BusinessInterval bi = bif.makeSaturdaySundayWeekend();
//  Now you've got everything you need to create the Timer Trigger for this task:timerTrigger.setBusinessInterval(bi);
timerTrigger.setTimeExpression(timeExpression);
timerTrigger.setEndDate(newYearsDay2003);

 

This Timer Trigger will fire at 1830 on the last weekday of every month until New Year’s Day 2002.

Relative time expressions

Relative time expressions specify an offset, relative to a particular point in time.

...

-12H+30s

Move backward 12 hours, then forward 30 seconds.

+23y-23M+23S-8m

Move forward 23 years, then backup 23 months, then move forward 23 milliseconds, then backup 8 minutes.

>sat

Move forward to Saturday.

>3sat>nov

Move forward 3 Saturdays, then skip ahead to November.

<5may>fri

Move backward 5 Mays, then advance to Friday.

@2005y+2y<sun

Go to the year 2005, then move forward 2 years, then backup to Sunday.

(2M)22d (8H)30m

Go to March 22nd, 8:30 AM of the current year.

^M>4mon

Go to the beginning of the month, then advance 4 Mondays.

+M^M>4mon

Go to the beginning of next month, then advance 4 Mondays.

^d+7H

Go to the beginning of today, then advance 7 hours.

>3D

Move forward three weekdays.

<4e

Move backward 4 weekend days.

>n

Move forward to the next non-holiday.

?D{+d}

If today is a weekday, advance a day.

?b{}{+2d}

If today is not a business day, advance two days.

A real world relative time expression example from our Technical Support department

Question: I want to define an activity that occurs each month on the last weekday at a particular time. For example, the last Thursday, 18:30, starting 1 January 2002, and ending 31 December 2002.

[Note: This example can be solved using a Cron-style Time Expression too. See Real world time expression examples from our Technical Support Department for more information.

Answer: Ok, so you want to run a task on the last weekday of the month at 1830. And the period you want to run this in is from 1 January 2002 through 31 December 2002.

First, you orient yourself to midnight on New Year's Day, 2002, like so:

 

Code Block
EngineHelper helper = factory.makeEngineHelper();
// New Year's Day 2002, at midnight
Date newYearsDay2002 = helper.makeDateInDefaultTimeZone("2002 Jan 1 00:00:00.000");
// New Year's Day 2003, at midnight
Date newYearsDay2003 = helper.makeDateInDefaultTimeZone("2003 Jan 1 00:00:00.000");
// Now find the last weekday at 1830 in January 2002.
Date lastWeekdayInJanuary = EngineHelper.applyTimeExpression(newYearsDay2002, "$M<D^d+18H+30m", null);

 

Let me explain that relative time expression a bit. $M takes you to the end of the current month. Then <D backs you up to the first weekday that it finds. ^d resets the time-of-day to midnight. Then +18H+30m advances you to 1830 on the last weekday of January 2002.

So now you know when the first task should fire. All you need now is a time expression to repeatedly apply so that your task fires every month at the proper time.String timeExpression = "+M$M<D^d+18H+30m";This time expression will be applied to a date that represents the last weekday of the current month. +M takes you into the next month. $M takes you to the end of that month. <D backs you up to the first weekday that it finds. ^d resets the time-of-day to midnight. And +18H+30m advances you to 1830 on the last weekday of the month.

Now you've got everything you need to create the Timer Trigger for this task:

Code Block
timerTrigger.setScheduledTriggerDate(lastWeekdayInJanuary);
timerTrigger.setTimeExpression(timeExpression);
timerTrigger.setEndDate(newYearsDay2003);

 

This Timer Trigger will fire at 1830 on the last weekday of every month throughout the year in 2002.

Designing and Testing Time Expressions

...