예제 #1
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 NullableDateTime GetWeeklyFireTimeAfter(DateTime afterDateUtc)
        {
            int  currN = 0;
            int  currWeek;
            int  weekCount = 0;
            bool gotOne    = false;

#if !NET_35
            afterDateUtc = TimeZone.ToLocalTime(afterDateUtc);
#else
            afterDateUtc = TimeZoneInfo.ConvertTimeFromUtc(afterDateUtc, TimeZone);
#endif
            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 !NET_35
                    if (EndTimeUtc.HasValue && TimeZone.ToUniversalTime(currCal) > EndTimeUtc.Value)
#else
                    if (EndTimeUtc.HasValue && TimeZoneInfo.ConvertTimeToUtc(currCal, TimeZone) > EndTimeUtc.Value)
#endif
                    {
                        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 !NET_35
                    if (afterDateUtc < TimeZone.ToUniversalTime(currCal))
#else
                    if (afterDateUtc < TimeZoneInfo.ConvertTimeToUtc(currCal, TimeZone))
#endif
                    {
                        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)
            {
#if !NET_35
                return(TimeZone.ToUniversalTime(currCal));
#else
                return(TimeZoneInfo.ConvertTimeToUtc(currCal, TimeZone));
#endif
            }
            else
            {
                return(null);
            }
        }