Exemple #1
0
        /// <summary>
        /// Gets the date and time of the next occurrence from <paramref name="now"/>.
        /// </summary>
        /// <param name="now">The current date and time assumed to be an universal time if not specified to avoid invalid and ambiguous times.</param>
        /// <returns>The date and time of the next occurrence in local time.</returns>
        protected override DateTime GetNextTime(DateTime inNow)
        {
            var now = inNow.AsLocalTime();

            // consider first occurrence
            var firstOccurrence = (timesOfDayQueue == null);

            // initialize timesOfDayQueue if necessary
            if (timesOfDayQueue == null)
            {
                // consider current dayOfWeek not in requested WeekDays
                if ((WeekDays & FlagsEnum.PowerOfTwo <RecurrentWeekDays>(now.DayOfWeek)) != FlagsEnum.PowerOfTwo <RecurrentWeekDays>(now.DayOfWeek))
                {
                    timesOfDayQueue = new Queue <TimeSpan>(TimesOfDay);
                }
                else
                {
                    // order the timesOfDay according to the current date and time
                    timesOfDayQueue = new Queue <TimeSpan>(TimesOfDay
                                                           .SkipWhile(match => match <= now.TimeOfDay)
                                                           .Concat(TimesOfDay)
                                                           .Take(TimesOfDay.Count())
                                                           .DefaultIfEmpty(TimesOfDay.First()));
                }
            }

            // remove the current timeOfDay from the queue
            var timeOfDay = timesOfDayQueue.Dequeue();

            // add the current timeOfDay to the end
            timesOfDayQueue.Enqueue(timeOfDay);

            // get today to maintain the specified timeOfDay across the daylight time
            var today = now.Date.AsLocalTime();

            // shift today if necessary in order to calculate correctly the next date
            if ((firstOccurrence && now.TimeOfDay < timeOfDay) ||
                (!firstOccurrence && timesOfDayQueue.Count > 1 && timeOfDay > timesOfDayQueue.Min()))
            {
                today = today.AddDays(-1);
            }

            // get the next date
            var nextDate = GetNextDateByDayOfWeek(today);

            // keep the found next date
            var index = (int)nextDate.DayOfWeek;

            if (nextDates[index] != null &&
                nextDates[index].Value < nextDate)
            {
                nextDate = nextDates[index].Value.AddDays(7 * Weeks);
            }
            nextDates[index] = nextDate;

            // consider next time validity
            if (TimeZoneContext.Current.TimeZoneInfo.IsInvalidTime(nextDate.Add(timeOfDay)) &&
                Behavior.InvalidTime == InvalidTimeBehavior.Skip)
            {
                // get the next valid time
                return(GetNextTime(nextDate));
            }

            // consider next time ambiguity
            if (TimeZoneContext.Current.TimeZoneInfo.IsAmbiguousTime(nextDate.Add(timeOfDay)) &&
                Behavior.AmbiguousTime == AmbiguousTimeBehavior.DaylightTime)
            {
                // get the next time from the universal time
                return(nextDate.AsUniversalTime().Add(timeOfDay).AsLocalTime());
            }

            // get the next time from the local time
            return(nextDate.Add(timeOfDay));
        }
Exemple #2
0
        /// <summary>
        /// Gets the date and time of the next occurrence from <paramref name="now"/>.
        /// </summary>
        /// <param name="now">The current date and time assumed to be an universal time if not specified to avoid invalid and ambiguous times.</param>
        /// <returns>The date and time of the next occurrence in local time.</returns>
        protected override DateTime GetNextTime(DateTime inNow)
        {
            if (inNow.Kind == DateTimeKind.Unspecified)
            {
                throw new InvalidTimeZoneException("DateTime Kind should be set. Unspecified is unsupported!");
            }


            var now = inNow.AsLocalTime();

            // consider first occurrence
            var firstOccurrence = (timesOfDayQueue == null);

            // initialize timesOfDayQueue if necessary
            if (timesOfDayQueue == null)
            {
                // consider current dayOfWeek not in requested WeekDays
                if (Days == 0 && (WeekDays & FlagsEnum.PowerOfTwo <RecurrentWeekDays>(now.DayOfWeek)) != FlagsEnum.PowerOfTwo <RecurrentWeekDays>(now.DayOfWeek))
                {
                    timesOfDayQueue = new Queue <TimeSpan>(TimesOfDay);
                }
                else
                {
                    // order the timesOfDay according to the current date and time
                    timesOfDayQueue = new Queue <TimeSpan>(TimesOfDay
                                                           .SkipWhile(match => match <= now.TimeOfDay)
                                                           .Concat(TimesOfDay)
                                                           .Take(TimesOfDay.Count())
                                                           .DefaultIfEmpty(TimesOfDay.First()));
                }
            }

            // remove the current timeOfDay from the queue
            var timeOfDay = timesOfDayQueue.Dequeue();

            // add the current timeOfDay to the end
            timesOfDayQueue.Enqueue(timeOfDay);

            // get today to maintain the specified timeOfDay across the daylight time
            var today = now.Date;

            // shift today if necessary in order to calculate correctly the next date
            if ((firstOccurrence && now.TimeOfDay < timeOfDay) ||
                (!firstOccurrence && timesOfDayQueue.Count > 1 && timeOfDay > timesOfDayQueue.Min()))
            {
                today = today.AddDays(Days != 0 ? -Days : -1);
            }

            // get the next date
            var nextDate = (Days != 0)
                    ? today.AddDays(Days)
                    : GetNextDateByDayOfWeek(today);

            // consider next time validity
            if (TimeZoneContext.Current.TimeZoneInfo.IsInvalidTime(nextDate.Add(timeOfDay)) &&
                Behavior.InvalidTime == InvalidTimeBehavior.Skip)
            {
                // get the next valid time
                return(GetNextTime(nextDate));
            }

            // consider next time ambiguity
            if (TimeZoneContext.Current.TimeZoneInfo.IsAmbiguousTime(nextDate.Add(timeOfDay)) &&
                Behavior.AmbiguousTime == AmbiguousTimeBehavior.DaylightTime)
            {
                // get the next time from the universal time
                return(nextDate.AsUniversalTime().Add(timeOfDay).AsLocalTime());
            }

            // get the next time from the local time
            return(nextDate.Add(timeOfDay));
        }