我正在使用Quartz CronTrigger工具来解析cron调度格式字符串,以确定何时应运行特定作业 . 我实际上并没有使用Quartz安排工作 .
CronTrigger中有一个名为getFireTimeAfter(Date)的方法,它给出下一次作业将在给定日期之后触发的时间 . 当提供的日期现在或将来时,这很有效 . 但如果日期已经过去,它似乎不起作用 .
Date currTime = new Date();
CronTrigger tr = new CronTrigger();
tr.setCronExpression("0 0 23 3,18 * ? *");
Date nextFireAt = tr.getFireTimeAfter(currTime);
System.out.println("Reference time: " + currTime);
System.out.println("Next fire after reference time: " + nextFireAt);
这是每月3日和18日23:00开火的cron时间表 . 例如,如果我今天(8月11日)这样做,我看到:
Reference time: Thu Aug 11 10:04:25 MDT 2011
Next fire after reference time: Thu Aug 18 23:00:00 MDT 2011
但是,如果我将参考日期设置为过去,它会给我相同的下一个开火时间 .
Reference time: Wed Dec 31 17:00:00 MST 1969
Next fire after reference time: Thu Aug 18 23:00:00 MDT 2011
我期待输出为:
Reference time: Wed Dec 31 17:00:00 MST 1969
Next fire after reference time: Wed Aug 3 23:00:00 MDT 2011
方法是不是打算以这种方式工作,还是我做错了什么?
谢谢!
5 回答
您真正想要直接使用CronExpression对象而不是CronTrigger . 正如您所发现的,它不会计算过去的下一次运行时间......但是CronExpression会!
CronExpression的方法有:getNextValidTimeAfter . 这就是你想要的 .
在Spring中,您可以遵循他们在集成测试中使用的相同方法 . CronTriggerTests
CronTrigger.getFireTimeAfter()
方法具有保护机制,用于防止指定的时间过去 .这可以通过在您评估过去的时间调用
setStartTime
firth来规避 . 然后对getFireTimeAfter
的调用应返回有效结果 .根据Quartz doc:
"Will fire"暗示"in the future" . 也就是说,下一次
CronTrigger
将不会过去,并且不会返回过去的日期 .我不确切地知道你想要什么,但你晚上对这些方法感兴趣:
getPreviousFireTime():返回触发器的最后一次触发
getTimeBefore():返回触发器在给定日期之前触发的时间(过去工作) - 注意:这个似乎现在没有实现
这有点奇怪,但存在保护机制 . 不知道为什么Quartz Team有这个检查 . 仅当我向
nxtDay
(nxtDay = nxtTrigger.Value.DateTime.AddHours(1);
)添加一小时时,以下测试才会通过