Example #1
0
        /// <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 &#x8212; 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);
            }
        }
Example #2
0
        /// <summary>
        /// Calculate and set the EndTimeOfDay using count, interval and StarTimeOfDay. This means
        /// that these must be set before this method is call.
        /// </summary>
        /// <param name="count"></param>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder EndingDailyAfterCount(int count)
        {
            if (count <= 0)
            {
                throw new ArgumentException("Ending daily after count must be a positive number!");
            }

            if (startTimeOfDayUtc == null)
            {
                throw new ArgumentException("You must set the StartDailyAt() before calling this EndingDailyAfterCount()!");
            }

            DateTimeOffset today = SystemTime.UtcNow();
            DateTimeOffset startTimeOfDayDate  = startTimeOfDayUtc.GetTimeOfDayForDate(today);
            DateTimeOffset maxEndTimeOfDayDate = TimeOfDay.HourMinuteAndSecondOfDay(23, 59, 59).GetTimeOfDayForDate(today);

            //apply proper offsets according to timezone
            TimeZoneInfo targetTimeZone = timeZone ?? TimeZoneInfo.Local;

            startTimeOfDayDate  = new DateTimeOffset(startTimeOfDayDate.DateTime, TimeZoneUtil.GetUtcOffset(startTimeOfDayDate.DateTime, targetTimeZone));
            maxEndTimeOfDayDate = new DateTimeOffset(maxEndTimeOfDayDate.DateTime, TimeZoneUtil.GetUtcOffset(maxEndTimeOfDayDate.DateTime, targetTimeZone));

            TimeSpan remainingMillisInDay = maxEndTimeOfDayDate - startTimeOfDayDate;
            TimeSpan intervalInMillis;

            if (intervalUnit == IntervalUnit.Second)
            {
                intervalInMillis = TimeSpan.FromSeconds(interval);
            }
            else if (intervalUnit == IntervalUnit.Minute)
            {
                intervalInMillis = TimeSpan.FromMinutes(interval);
            }
            else if (intervalUnit == IntervalUnit.Hour)
            {
                intervalInMillis = TimeSpan.FromHours(interval);
            }
            else
            {
                throw new ArgumentException("The IntervalUnit: " + intervalUnit + " is invalid for this trigger.");
            }

            if (remainingMillisInDay < intervalInMillis)
            {
                throw new ArgumentException("The startTimeOfDay is too late with given Interval and IntervalUnit values.");
            }

            long maxNumOfCount = remainingMillisInDay.Ticks / intervalInMillis.Ticks;

            if (count > maxNumOfCount)
            {
                throw new ArgumentException("The given count " + count + " is too large! The max you can set is " + maxNumOfCount);
            }

            TimeSpan       incrementInMillis = TimeSpan.FromTicks((count - 1) * intervalInMillis.Ticks);
            DateTimeOffset endTimeOfDayDate  = startTimeOfDayDate.Add(incrementInMillis);

            if (endTimeOfDayDate > maxEndTimeOfDayDate)
            {
                throw new ArgumentException("The given count " + count + " is too large! The max you can set is " + maxNumOfCount);
            }

            DateTime cal = SystemTime.UtcNow().Date;

            cal             = cal.Add(endTimeOfDayDate.TimeOfDay);
            endTimeOfDayUtc = TimeOfDay.HourMinuteAndSecondOfDay(cal.Hour, cal.Minute, cal.Second);
            return(this);
        }
Example #3
0
        /// <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 &#x8212; 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);
            }
        }