Java – Converting cron schedule to time intervals

algorithmscrongroovyjavascheduling

I have, on the server, many jobs defined by users and some of those jobs are scheduled using cron expressions. I need to check (I can execute Groovy/Java on the server) if those jobs take longer than they are scheduled (I mean job is taking 10 minutes, but scheduled to run every 5 minutes).

I have been trying to find something that converts cron expression to time interval(s). This seems to be doing pretty good job converting cron expressions to human-readable strings, but what about getting the shortest time interval?

Is the solution to recursively loop from years to seconds and add every time found to list, calculate each time interval and find the smallest from there? Or does a better way exist?

Example, say we have a cron expression: 0 0 11,16,19,21 * * *
This translates to: Every year every month every day at 11:00, 16:00, 19:00 and 21:00. That gives us intervals: 5h, 3h, 2h and 14h. I am interested in the shortest interval – 2h.

I do understand that this can quickly get very complex and result in gazillion intervals, but I was randomly looking thru the expressions that I would need to calculate and they are rather easy. While waiting here for an answer, I discovered Quartz library. I can give it a cron expression and simply ask it "when is next, when is next etc". So if I'd ask.. say 5 times, I probably have most of my cases covered. I have to check how it performs. If anybody has a better solution, I warmly welcome it.

Best Answer

If you need to consider multiple crontab entries for the same task, you will have to iterate through a full 400-year Gregorian cycle. For example:

59 23 29 2 * me /home/me/mytask # 11:59 Feb 29
01 00  1 3 * me /home/me/mytask # 00:01 Mar 1

These events will occur two minutes apart every leap year

Worse:

59 23 29 2 * me /home/me/mytask # 11:59 Feb 29
01 00  * * 0 me /home/me/mytask # 00:01 Sunday

These events will occur two minutes apart when Feb 29 falls on Saturday.

Another difficult case for systems where the cron daemon uses local time:

0 1,3 * * * me /home/me/mytask # 01:00 and 03:00

These jobs will run two hours apart except on the morning when DST begins. On that morning they will run one hour apart.

Related Topic