Java 石英触发-获得下一次射击时间

Java 石英触发-获得下一次射击时间,java,cron,quartz-scheduler,Java,Cron,Quartz Scheduler,我正在使用Quartz CronTrigger工具解析cron调度格式字符串,以确定特定作业应在何时运行。不过,我实际上并没有使用Quartz来安排工作 CronTrigger中有一个名为getFireTimeAfter(Date)的方法,它给出了作业在给定日期后的下一次触发时间。当所提供的日期是现在或将来时,这种方法很有效。但如果日期是过去的话,这似乎不起作用 Date currTime = new Date(); CronTrigger tr = new CronTrigger(); tr.

我正在使用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: 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
这个方法是不是不打算这样做,还是我做错了什么

谢谢

根据:

返回给定时间后CronTrigger将触发的下一次时间

“将火”意味着“在未来”。也就是说,下次触发
CronTrigger
的时间不是过去,并且不会返回过去的日期

我不知道你到底想实现什么,但你可能对这些方法感兴趣:

  • getPreviousFireTime():返回上次触发触发器的时间
  • getTimeBefore():返回在给定日期之前触发的触发器的时间(在过去有效)——注意:这一项目前似乎尚未实现

您真正想要使用的是CronExpression对象,而不是CronTrigger。正如您所发现的,它不会计算过去的下一次运行时间。。。但我会的


CronExpression的方法为:getNextValidTimeAfter。这就是您想要的。

CronTrigger.getFireTimeAfter()方法具有一种保护机制,用于防止指定的after时间成为过去

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);

使用您正在评估的过去时间调用
setStartTime
firth可以避免这种情况。然后对
getFireTimeAfter
的调用应该返回一个有效的结果。

这有点奇怪,但是保护机制存在。不知道石英团队为什么有那个支票。仅当我在
nxtDay中添加一小时时,以下测试才通过
(
nxtDay=nxtTrigger.Value.DateTime.AddHours(1);


在Spring中,您可以遵循他们在集成测试中使用的相同方法。


我试图使用CronTrigger来知道是否已经发生了某个“到期日”。我拥有的两条信息是“最后到期日时间”和cron时间表。所以我想做的是获取FireTimeAfter(lastDueDate)来告诉我是否超过了当前的到期日。看起来getTimeBefore()可能就是我想要的——可惜它还没有实现。@Kal-是的,我知道。我想知道在给定的日期之后,触发器什么时候会触发,即使是在过去。是的!这正是我要找的!谢谢有没有办法找到datetime范围内的所有事件?@ManikArora:您可以先将开始日期时间作为参数传递,然后在每次迭代中返回所有时间戳,然后在这些时间戳仍然小于结束时间时进行while循环调用GetNextValidTimes。在每次迭代中,可以将结果日期添加到事件列表中。
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");

//FREQUENCY OF SECONDS 
var reccurrence = new Reccurrence
{
    StartTime = new TimeSpan(9, 0, 0),
    StopTime = new TimeSpan(11, 0, 0),
    WeekDay = "MON-SUN",
    TimeZoneInfo = timeZoneInfo,
    Frequency = 15,
    FrequencyUnit = FrequencyUnit.Seconds
};

var autoPublishDetail = new AutoPublishJobDetail("TestReccurence_Seconds", _log, null, reccurrence);
var trigger = autoPublishDetail.GetDailyTrigger();
var nxt = trigger.GetNextFireTimeUtc();

var jobSeconds = JobBuilder.Create().WithIdentity(new JobKey("TestReccurence_Seconds")).OfType(typeof(AutoPublishJob)).Build();

_scheduler.ScheduleJob(jobSeconds, trigger);

//This job sud run 4 times in a 60 secs and from 9 am to 11 am (Span of 3 hrs including 11 onwards to 11:59:59)
//Total runs = 4 x 60 x 3 = 720
var today = DateTime.Now;
var tomorrow = today.AddDays(1);
DateTime? nxtDay = new DateTime(tomorrow.Year, tomorrow.Month, tomorrow.Day);

int jobCnt = 0;
do
{
    var nxtTrigger = trigger.GetFireTimeAfter(nxtDay.Value);

    if (nxtTrigger.Value.Year.Equals(today.AddDays(2).Year) && nxtTrigger.Value.Month.Equals(today.AddDays(2).Month) && nxtTrigger.Value.Day.Equals(today.AddDays(2).Day))
        break;

    jobCnt++;
    nxtDay = nxtTrigger.Value.DateTime.AddHours(1);

} while (true);

Assert.AreEqual(720, jobCnt);
CronTrigger trigger = new CronTrigger();
trigger.setCronExpression("0 0 23 3,18 * ? *");
SimpleTriggerContext triggerContext = new SimpleTriggerContext();
triggerContext.update(null, null, new Date());
Date nextFireAt = trigger.nextExecutionTime(triggerContext);