令人惊讶的是,仍然没有基于 CronExpression 获取先前触发时间的石英方法......
如何获得最后一次解雇时间?
如果您正在操作基本的 CRON,例如0 0 0 * * ?
(每天上午 00:00:00),您可以使用 João Neves 的解决方案(使用 com.cronutils.model.time.ExecutionTime)。
否则,如果您正在操纵复杂的 CRON 0 30 11 ? * MON,THU *
,它将无法正常工作。你会得到随机结果(我有一个星期三的这个......)。
编辑:我做了其他测试,最新版本看起来效果更好(以前的测试是用 < 3.1.6 的版本进行的)。注意:如果要使用版本 > 3.1.6,则需要 Java 8。
您可以使用的解决方案是在您的工作被触发时存储它。
如何验证作业是否已触发?
我找到的解决方案是使用getNextValidTimeAfter
Quartz (CronExpression)。这个工作正常。你会问我在说什么,因为我们正在寻找以前的有效时间!你是对的,给我一秒钟!
假设我们有一个每月一次的 CRON(0 0 16 1 * ? = 每月第一天下午 16:00:00),我们想每天检查前一次执行是否有效。您必须在每次执行时存储 getNextValidTime 并将此日期与今天的日期进行比较。例如(格式 DD/MM/YYYY):
• 01/01/2019 → 作业触发,我们存储下一次触发时间(我们称之为nextFireTime
):
CronExpression trigger = new CronExpression("0 0 16 1 * ?");
Date nextFireTime = trigger.getNextValidTimeAfter(new Date());
// = 01/02/2019
• 02/01/2019 → 当天验证:02/01/2019 < 01/02/2019 OK
...
• 01/02/2019 → 假设服务器已关闭,作业未触发。
• 02/02/2019 → 服务器开启,当天验证:02/02/2019 > 01/02/2019 KO !
→ 我们知道之前的开火时间没有奏效。你可以知道做你想做的事(触发工作并存储新的 nextFireTime)。
您可能感兴趣的另一个选项,请参阅MISFIRE_INSTRUCTION_FIRE_NOW。
该作业在调度程序发现失火情况后立即执行。这是明智的政策。示例场景:您已安排在凌晨 2 点进行一些系统清理。不幸的是,由于当时的维护,该应用程序已关闭,并在凌晨 3 点恢复。所以触发器失火了,调度程序试图通过尽快运行来挽救这种情况——在凌晨 3 点。
来自(https://dzone.com/articles/quartz-scheduler-misfire)
例如:
Trigger trigger = newTrigger().
withSchedule(
cronSchedule("0 0 9-17 ? * MON-FRI").
withMisfireHandlingInstructionFireAndProceed()
).
build();
官方文档:https ://www.quartz-scheduler.org/api/2.1.7/org/quartz/CronTrigger.html