簡體   English   中英

Quartz CronTrigger - 獲得下一個火力時間

[英]Quartz CronTrigger - Getting next fire time

我正在使用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

方法是不是打算以這種方式工作,還是我做錯了什么?

謝謝!

您真正想要直接使用CronExpression對象而不是CronTrigger。 正如您所發現的,它不會計算過去的下一次運行時間......但是CronExpression會!

CronExpression的方法有:getNextValidTimeAfter。 這就是你想要的。

在Spring中,您可以遵循他們在集成測試中使用的相同方法。 CronTriggerTests

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

CronTrigger.getFireTimeAfter()方法具有一種保護機制,用於防止指定的時間過去。

這可以通過調用setStartTime firth與您正在評估的過去時間來規避。 然后對getFireTimeAfter的調用應返回有效結果。

這有點奇怪,但存在保護機制。 不知道為什么Quartz Team有這個檢查。 僅當我向nxtDay添加一小時時,以下測試才會通過( nxtDay = nxtTrigger.Value.DateTime.AddHours(1);

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

根據Quartz doc

在給定時間之后返回CronTrigger下次觸發的時間

“意志火”意味着“未來”。 也就是說, CronTrigger下次觸發時不會過去,並且不會返回過去的日期。

我不確切地知道你想要什么,但你晚上對這些方法感興趣:

  • getPreviousFireTime():返回觸發器的最后一次觸發
  • getTimeBefore():返回觸發器在給定日期之前觸發的時間(過去工作) - 注意:這個似乎現在沒有實現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM