/// <summary> /// Calculates the first time an <see cref="NthIncludedDayTrigger" /> with /// intervalType = <see cref="IntervalTypeYearly" /> will fire /// after the specified date. See <see cref="GetNextFireTimeUtc" /> for more /// information. /// </summary> /// <param name="afterDateUtc"> /// The UTC time after which to find the nearest fire time. /// This argument is treated as exclusive 舒 that is, /// if afterTime is a valid fire time for the trigger, it /// will not be returned as the next fire time. /// </param> /// <returns> the first time the trigger will fire following the specified /// date /// </returns> private DateTimeOffset?GetYearlyFireTimeAfter(DateTimeOffset afterDateUtc) { int currN = 0; DateTimeOffset currCal = TimeZoneUtil.ConvertTime(afterDateUtc, TimeZone); currCal = new DateTime(currCal.Year, 1, 1, fireAtHour, fireAtMinute, fireAtSecond, 0); int currYear; int yearCount = 0; bool gotOne = false; currYear = currCal.Year; while ((!gotOne) && (yearCount < nextFireCutoffInterval)) { while ((currN != n) && (yearCount < 5)) { //if we move into a new year, reset the current "n" counter if (currCal.Year != currYear) { currN = 0; yearCount++; currYear = currCal.Year; } //treating a null calendar as an all-inclusive calendar, // increment currN if the current date being tested is included // on the calendar if (calendar == null || calendar.IsTimeIncluded(currCal)) { currN++; } if (currN != n) { currCal = currCal.AddDays(1); } //if we pass endTime, drop out and return null. if (EndTimeUtc.HasValue && TimeZoneUtil.ConvertTime(currCal, TimeZone) > EndTimeUtc.Value) { return(null); } } //We found an "n" or we've checked the requisite number of years. // If we've found an "n", is it the right one? -- that is, we // could be looking at an nth day PRIOR to afterDateUtc if (currN == n) { if (afterDateUtc < TimeZoneUtil.ConvertTime(currCal, TimeZone)) { gotOne = true; } else { //resume checking on the first day of the next year currCal = new DateTime(currCal.Year + 1, 1, 1, currCal.Hour, currCal.Minute, currCal.Second); currN = 0; } } } if (yearCount < nextFireCutoffInterval) { return(TimeZoneUtil.ConvertTime(currCal, TimeZone)); } else { return(null); } }
/// <summary> /// Calculates the first time an <see cref="NthIncludedDayTrigger" /> with /// <c>intervalType = IntervalTypeWeekly</c> will fire /// after the specified date. See <see cref="GetNextFireTimeUtc" /> for more /// information. /// </summary> /// <param name="afterDateUtc">The time after which to find the nearest fire time. /// This argument is treated as exclusive 舒 that is, /// if afterTime is a valid fire time for the trigger, it /// will not be returned as the next fire time. /// </param> /// <returns> the first time the trigger will fire following the specified /// date /// </returns> private DateTimeOffset?GetWeeklyFireTimeAfter(DateTimeOffset afterDateUtc) { int currN = 0; int currWeek; int weekCount = 0; bool gotOne = false; afterDateUtc = TimeZoneUtil.ConvertTime(afterDateUtc, TimeZone); DateTime currCal = new DateTime(afterDateUtc.Year, afterDateUtc.Month, afterDateUtc.Day); // move to the first day of the week // TODO, we are still bound to fixed local time zone as with TimeZone property while (currCal.DayOfWeek != DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek) { currCal = currCal.AddDays(-1); } currCal = new DateTime(currCal.Year, currCal.Month, currCal.Day, fireAtHour, fireAtMinute, fireAtSecond, 0); currWeek = GetWeekOfYear(currCal); while ((!gotOne) && (weekCount < nextFireCutoffInterval)) { while ((currN != n) && (weekCount < 12)) { //if we move into a new week, reset the current "n" counter if (GetWeekOfYear(currCal) != currWeek) { currN = 0; weekCount++; currWeek = GetWeekOfYear(currCal); } //treating a null calendar as an all-inclusive calendar, // increment currN if the current date being tested is included // on the calendar if ((calendar == null) || calendar.IsTimeIncluded(currCal)) { currN++; } if (currN != n) { currCal = currCal.AddDays(1); } //if we pass endTime, drop out and return null. if (EndTimeUtc.HasValue && TimeZoneInfo.ConvertTimeToUtc(currCal, TimeZone) > EndTimeUtc.Value) { return(null); } } // We found an "n" or we've checked the requisite number of weeks. // If we've found an "n", is it the right one? -- that is, we could // be looking at an nth day PRIOR to afterDateUtc if (currN == n) { if (afterDateUtc < TimeZoneInfo.ConvertTimeToUtc(currCal, TimeZone)) { gotOne = true; } else { // resume checking on the first day of the next week // move back to the beginning of the week and add 7 days // TODO, need to correlate with time zone in .NET 3.5 while (currCal.DayOfWeek != DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek) { currCal = currCal.AddDays(-1); } currCal = currCal.AddDays(7); currN = 0; } } } if (weekCount < nextFireCutoffInterval) { return(TimeZoneInfo.ConvertTimeToUtc(currCal, TimeZone)); } else { return(null); } }