/// <summary> /// This method should not be used by the Quartz client. /// </summary> /// <remarks> /// <para> /// Called by the scheduler at the time a <see cref="ITrigger" /> is first /// added to the scheduler, in order to have the <see cref="ITrigger" /> /// compute its first fire time, based on any associated calendar. /// </para> /// /// <para> /// After this method has been called, <see cref="ITrigger.GetNextFireTimeUtc" /> /// should return a valid answer. /// </para> /// </remarks> /// <returns> /// The first time at which the <see cref="ITrigger" /> will be fired /// by the scheduler, which is also the same value <see cref="ITrigger.GetNextFireTimeUtc" /> /// will return (until after the first firing of the <see cref="ITrigger" />). /// </returns> public override DateTimeOffset?ComputeFirstFireTimeUtc(ICalendar calendar) { DateTimeOffset startTime = StartTimeUtc; DateTimeOffset?startTimeOfDayDate = StartTimeOfDayUtc.GetTimeOfDayForDate(startTime); // If startTime is after the timeOfDay, then use starTime if (startTime > startTimeOfDayDate) { nextFireTimeUtc = GetFireTimeAfter(startTime); } else { nextFireTimeUtc = AdvanceToNextDayOfWeek(startTimeOfDayDate.Value, false); } // Check calendar for date-time exclusion while (nextFireTimeUtc != null && calendar != null && !calendar.IsTimeIncluded(nextFireTimeUtc.Value)) { nextFireTimeUtc = GetFireTimeAfter(nextFireTimeUtc); if (nextFireTimeUtc == null) { break; } //avoid infinite loop if (nextFireTimeUtc.Value.Year > YearToGiveupSchedulingAt) { return(null); } } return(nextFireTimeUtc); }
/// <summary> /// Returns the next time at which the <code>DailyTimeIntervalTrigger</code> will /// fire, after the given time. If the trigger will not fire after the given /// time, <code>null</code> will be returned. /// </summary> /// <param name="afterTime"></param> /// <returns></returns> public override DateTimeOffset?GetFireTimeAfter(DateTimeOffset?afterTime) { // Check if trigger has completed or not. if (complete) { return(null); } // Check repeatCount limit if (repeatCount != RepeatIndefinitely && timesTriggered > repeatCount) { return(null); } // a. Increment afterTime by a second, so that we are comparing against a time after it! if (afterTime == null) { afterTime = SystemTime.UtcNow().AddSeconds(1); } else { afterTime = afterTime.Value.AddSeconds(1); } // b.Check to see if afterTime is after endTimeOfDay or not. // If yes, then we need to advance to next day as well. bool afterTimePassEndTimeOfDay = false; if (endTimeOfDayUtc != null) { afterTimePassEndTimeOfDay = afterTime.Value > endTimeOfDayUtc.GetTimeOfDayForDate(afterTime).Value; } DateTimeOffset?fireTime = AdvanceToNextDayOfWeek(afterTime.Value, afterTimePassEndTimeOfDay); if (fireTime == null) { return(null); } // c. Calculate and save fireTimeEndDate variable for later use DateTimeOffset fireTimeEndDate; if (endTimeOfDayUtc == null) { fireTimeEndDate = new TimeOfDay(23, 59, 59).GetTimeOfDayForDate(fireTime).Value; } else { fireTimeEndDate = endTimeOfDayUtc.GetTimeOfDayForDate(fireTime).Value; } // e. Check fireTime against startTime or startTimeOfDay to see which go first. DateTimeOffset fireTimeStartDate = startTimeOfDayUtc.GetTimeOfDayForDate(fireTime).Value; if (fireTime < startTimeUtc && startTimeUtc < fireTimeStartDate) { return(fireTimeStartDate); } else if (fireTime < startTimeUtc && startTimeUtc > fireTimeStartDate) { return(startTimeUtc); } else if (fireTime > startTimeUtc && fireTime < fireTimeStartDate) { return(fireTimeStartDate); } // Always adjust the startTime to be startTimeOfDay startTimeUtc = fireTimeStartDate; // f. Continue to calculate the fireTime by incremental unit of intervals. //long fireMillis = fireTime.Millisecond; //long startMillis = startTimeUtc.Millisecond; long secondsAfterStart = (long)(fireTime.Value - startTimeUtc).TotalSeconds; long repeatLong = RepeatInterval; DateTimeOffset aTime = CreateCalendarTime(fireTime.Value); DateTimeOffset sTime = CreateCalendarTime(startTimeUtc); IntervalUnit repeatUnit = RepeatIntervalUnit; if (repeatUnit == IntervalUnit.Second) { long jumpCount = secondsAfterStart / repeatLong; if (secondsAfterStart % repeatLong != 0) { jumpCount++; } sTime = sTime.AddSeconds(RepeatInterval * (int)jumpCount); fireTime = sTime; } else if (repeatUnit == IntervalUnit.Minute) { long jumpCount = secondsAfterStart / (repeatLong * 60L); if (secondsAfterStart % (repeatLong * 60L) != 0) { jumpCount++; } sTime = sTime.AddMinutes(RepeatInterval * (int)jumpCount); fireTime = sTime; } else if (repeatUnit == IntervalUnit.Hour) { long jumpCount = secondsAfterStart / (repeatLong * 60L * 60L); if (secondsAfterStart % (repeatLong * 60L * 60L) != 0) { jumpCount++; } sTime = sTime.AddHours(RepeatInterval * (int)jumpCount); fireTime = sTime; } // g. Ensure this new fireTime is within one day, or else we need to advance to next day. if (fireTime > fireTimeEndDate) { // Check to see if fireTime has pass fireTime's end of day. If not, we need to advance by one day. DateTimeOffset fireTimeEndOfDay = new TimeOfDay(23, 59, 59).GetTimeOfDayForDate(fireTimeEndDate).Value; if (fireTime > fireTimeEndOfDay) { fireTime = AdvanceToNextDayOfWeek(fireTime.Value, false); } else { fireTime = AdvanceToNextDayOfWeek(fireTime.Value, true); } if (fireTime == null) { return(null); } // Check to see if next day fireTime is before startTimeOfDay, if not, we need to set to startTimeOfDay. DateTimeOffset nextDayfireTimeStartDate = StartTimeOfDayUtc.GetTimeOfDayForDate(fireTime).Value; if (fireTime < nextDayfireTimeStartDate) { fireTime = nextDayfireTimeStartDate; } } // i. Return calculated fireTime. return(fireTime); }