Time Expressions in Java

Using Cron For Loops

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.

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:


// 0 0 (15 10; 30 12; */15 *) * * *
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 Cron 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.

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.

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.

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:

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).

[Note: This example can also be solved using a Relative Time Expression. See A real world relative time expression example 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, create a Date object that represents the beginning of the new year in 2003, like so:

// 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:

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.

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:

//  New Year's Day 2002, at midnight
Date newYearsDay2002 = EngineHelper.makeDateInDefaultTimeZone("2002 Jan 1 00:00:00.000");

//  New Year's Day 2003, at midnight
Date newYearsDay2003 = EngineHelper.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:

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.