It's amazing that there is still no quartz method for getting the previous fired time based on a CronExpression...
How to get last fired time ?
If you are manipulating basic CRON like 0 0 0 * * ?
(At 00:00:00am every day) you can use João Neves' solution (using com.cronutils.model.time.ExecutionTime).
Otherwise if you are manipulating complex CRON like 0 30 11 ? * MON,THU *
it will not works. You'll get random results (I had a Wednesday for this one...).
Edit: I did other tests and it looks working better with the latest version (previous tests were made with version < 3.1.6). Note: You need Java 8 if you want to use version > 3.1.6.
The solution you can use is to store it when your job is triggered.
How to verify that the job has been triggered ?
The solution I found is to use getNextValidTimeAfter
from Quartz (CronExpression). This one works fine.
You'll ask me what I'm talking about as we are looking for the previous valid time ! You are right, give me one second !
Let's imagine we have a once a month CRON (0 0 16 1 * ? = At 16:00:00pm, on the 1st day, every month) and we want to check everyday that the previous execution worked.
You'll have to store the getNextValidTime at each execution and compare this date with today's date. eg (format DD/MM/YYYY):
• 01/01/2019 → job triggered, we store next fire time (let's call it nextFireTime
):
CronExpression trigger = new CronExpression("0 0 16 1 * ?");
Date nextFireTime = trigger.getNextValidTimeAfter(new Date());
// = 01/02/2019
• 02/01/2019 → verification of the day: 02/01/2019 < 01/02/2019 OK
...
• 01/02/2019 → let's imagine server is down, the job is not triggered.
• 02/02/2019 → server on, verification of the day: 02/02/2019 > 01/02/2019 KO !
→ We know the previous fire time hasn't worked. You can know do what you want (trigger the job and store the new nextFireTime).
Another option that may interest you, see MISFIRE_INSTRUCTION_FIRE_NOW.
The job is executed immediately after the scheduler discovers misfire
situation. This is the smart policy. Example scenario: you have
scheduled some system clean up at 2 AM. Unfortunately the application
was down due to maintenance by that time and brought back on 3 AM. So
the trigger misfired and the scheduler tries to save the situation by
running it as soon as it can - at 3 AM.
From (https://dzone.com/articles/quartz-scheduler-misfire)
e.g.:
Trigger trigger = newTrigger().
withSchedule(
cronSchedule("0 0 9-17 ? * MON-FRI").
withMisfireHandlingInstructionFireAndProceed()
).
build();
Official doc: https://www.quartz-scheduler.org/api/2.1.7/org/quartz/CronTrigger.html