0
votes

I'm trying to come up with a CRON expression that will allow me to schedule a quartz trigger to run on every Monday in a month except the first one.

References:

CRON allows you to specify the nth occurrence of a day of the week easily. An expression for First Monday of the month would be:

0 5 0 ? * 2#1

Where the 2#1 represents the first Monday of the month (2 = day of the week, 1 being the nth occurrence)

However, if I try to do something like

0 5 0 ? * 2#2-2#5

OR

0 5 0 ? * 2#2,2#3,2#4,2#5

It complains with the message

 Support for specifying multiple "nth" days is not implemented.

Does anyone know how to achieve this in CRON?

1
This seems to be a common issue from what I have seen. The best answer seems to be use a SimpleTrigger or CalendarIntervalTrigger.Jeremy
@Jeremy, even then its difficult to achieve this use case. Only way i can think of is to have multiple triggers (one each for 2,3,4,5 monday's in a month)Srinivas
Very good point. Personally I would create multiple triggers. The SimpleTrigger or CalendarIntervalTrigger was the only way I could think to (maybe) centralizing it into one Cron job.Jeremy
@Srinivas: This was the approach I had to use. Having multiple copies of a single functional scheduler to cover all execution points look ugly but given the CRON expression limitation and my project's architecture I had no other option. It would be great if CRON can be enhanced to allow nth day rangesBakaTono

1 Answers

0
votes

Where cron doesn't give you the expressiveness you desire(a), it's a simple matter to change the command itself to only execute under certain conditions.

For your particular case, you know that the first Monday of a month is between the first and seventh inclusive and subsequent Mondays must be on the eighth or later.

So use cron to select all Mondays but slightly modify the command to exclude the first one in the month:

# mm hh dom mon dow command
   0  1   *   *   1 [[ $(date +%u) -gt 7 ]] && doSomething

That job will run at 1am every Monday but the actual payload doSomething will only be executed if the day of the month is greater than seven.

Some people often opt for putting the test into the script itself (assuming it even is a script) but I'm not a big fan of that, preferring to keep all scheduling information in the crontab file itself.


(a) Don't be mistaken into thinking you can combine the day of week 1 and day of month 8-31 to do this. As per the man page, those conditions are OR'ed (meaning either will allow the job to run):

Commands are executed by cron when the minute, hour, and month of year fields match the current time, and when at least one of the two day fields (day of month, or day of week) match the current time

Combining those two will run the job on the first Monday and every single day from the eighth onwards.