Пример #1
1
        /// <summary>
        /// This is used to find the starting point for the weekly frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="start">The recurrence start date</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="from">The start date of the range limiting the instances generated</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <returns>The first instance date or null if there are no more instances</returns>
        public RecurDateTime FindStart(Recurrence r, RecurDateTime start, RecurDateTime end, RecurDateTime from,
          RecurDateTime to)
        {
            RecurDateTime rdtWeek, rdt = new RecurDateTime(start);
            int adjust;

            // Get the difference between the recurrence start and the limiting range start
            DateTime dtStart = start.ToDateTime().Date.AddDays(0 - r.weekdayOffset);

            DateTime dtFrom = from.ToDateTime().Date;
            dtFrom = dtFrom.AddDays(0 - ((int)dtFrom.DayOfWeek + 7 - (int)r.WeekStart) % 7);

            // Adjust the date so that it's in range
            if(dtStart < dtFrom)
            {
                TimeSpan ts = dtFrom - dtStart;

                adjust = (ts.Days / 7) + r.Interval - 1;
                rdt.AddDays((adjust - (adjust % r.Interval)) * 7);
            }

            // If the start of the week is after the ranges, stop now
            rdtWeek = new RecurDateTime(rdt);
            rdtWeek.AddDays(0 - r.weekdayOffset);

            if(RecurDateTime.Compare(rdtWeek, end, RecurDateTime.DateTimePart.Day) > 0 ||
              RecurDateTime.Compare(rdtWeek, to, RecurDateTime.DateTimePart.Day) > 0)
                return null;

            return rdt;
        }
Пример #2
0
        /// <summary>
        /// This is used to expand the yearly frequency by year day
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public int ByYearDay(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;

            int expIdx, yearDay, count = dates.Count;

            UniqueIntegerCollection byYearDay = r.ByYearDay;

            // Don't bother if either collection is empty
            if (count != 0 && byYearDay.Count != 0)
            {
                for (int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each year day specified
                    for (expIdx = 0; expIdx < byYearDay.Count; expIdx++)
                    {
                        yearDay = byYearDay[expIdx];
                        rdtNew  = new RecurDateTime(rdt)
                        {
                            Month = 0, Day = 1
                        };

                        // From start of year or end of year?
                        if (yearDay > 0)
                        {
                            rdtNew.AddDays(yearDay - 1);
                        }
                        else
                        {
                            rdtNew.Year++;
                            rdtNew.AddDays(yearDay);
                        }

                        // If not in the year, discard it
                        if (rdtNew.Year != rdt.Year)
                        {
                            continue;
                        }

                        dates.Add(rdtNew);
                    }
                }
            }

            return(dates.Count);
        }
Пример #3
0
        /// <summary>
        /// This is used to expand by month day
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public static int ByMonthDay(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            int           expIdx, monthDay, count = dates.Count;

            UniqueIntegerCollection byMonthDay = r.ByMonthDay;

            // Don't bother if either collection is empty
            if (count != 0 && byMonthDay.Count != 0)
            {
                for (int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each month day specified
                    for (expIdx = 0; expIdx < byMonthDay.Count; expIdx++)
                    {
                        monthDay = byMonthDay[expIdx];
                        rdtNew   = new RecurDateTime(rdt)
                        {
                            Day = 1
                        };

                        // From start of month or end of month?
                        if (monthDay > 0)
                        {
                            rdtNew.AddDays(monthDay - 1);
                        }
                        else
                        {
                            rdtNew.AddMonths(1);
                            rdtNew.AddDays(monthDay);
                        }

                        // If not in the month, discard it
                        if (rdtNew.Month != rdt.Month)
                        {
                            continue;
                        }

                        dates.Add(rdtNew);
                    }
                }
            }

            return(dates.Count);
        }
Пример #4
0
        /// <summary>
        /// This is used to find the starting point for the daily frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="start">The recurrence start date</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="from">The start date of the range limiting the instances generated</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <returns>The first instance date or null if there are no more instances</returns>
        public RecurDateTime FindStart(Recurrence r, RecurDateTime start, RecurDateTime end, RecurDateTime from,
                                       RecurDateTime to)
        {
            RecurDateTime rdt = new RecurDateTime(start);
            int           adjust;

            // Get the difference between the recurrence start and the limiting range start
            DateTime dtStart = start.ToDateTime().Date, dtFrom = from.ToDateTime().Date;

            // Adjust the date so that it's in range
            if (dtStart < dtFrom)
            {
                TimeSpan ts = dtFrom - dtStart;

                adjust = ts.Days + r.Interval - 1;
                rdt.AddDays(adjust - (adjust % r.Interval));
            }

            if (RecurDateTime.Compare(rdt, end, RecurDateTime.DateTimePart.Day) > 0 ||
                RecurDateTime.Compare(rdt, to, RecurDateTime.DateTimePart.Day) > 0)
            {
                return(null);
            }

            return(rdt);
        }
Пример #5
0
        /// <summary>
        /// This is used to find the starting point for the weekly frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="start">The recurrence start date</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="from">The start date of the range limiting the instances generated</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <returns>The first instance date or null if there are no more instances</returns>
        public RecurDateTime FindStart(Recurrence r, RecurDateTime start, RecurDateTime end, RecurDateTime from,
                                       RecurDateTime to)
        {
            RecurDateTime rdtWeek, rdt = new RecurDateTime(start);
            int           adjust;

            // Get the difference between the recurrence start and the limiting range start
            DateTime dtStart = start.ToDateTime().Date.AddDays(0 - r.weekdayOffset);

            DateTime dtFrom = from.ToDateTime().Date;

            dtFrom = dtFrom.AddDays(0 - ((int)dtFrom.DayOfWeek + 7 - (int)r.WeekStart) % 7);

            // Adjust the date so that it's in range
            if (dtStart < dtFrom)
            {
                TimeSpan ts = dtFrom - dtStart;

                adjust = (ts.Days / 7) + r.Interval - 1;
                rdt.AddDays((adjust - (adjust % r.Interval)) * 7);
            }

            // If the start of the week is after the ranges, stop now
            rdtWeek = new RecurDateTime(rdt);
            rdtWeek.AddDays(0 - r.weekdayOffset);

            if (RecurDateTime.Compare(rdtWeek, end, RecurDateTime.DateTimePart.Day) > 0 ||
                RecurDateTime.Compare(rdtWeek, to, RecurDateTime.DateTimePart.Day) > 0)
            {
                return(null);
            }

            return(rdt);
        }
Пример #6
0
        /// <summary>
        /// This is used to find the next instance of the daily frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <param name="last">This is used to pass in the last instance date calculated and return the next
        /// instance date</param>
        /// <returns>True if the recurrence has another instance or false if there are no more instances</returns>
        public bool FindNext(Recurrence r, RecurDateTime end, RecurDateTime to, RecurDateTime last)
        {
            last.AddDays(r.Interval);

            if(RecurDateTime.Compare(last, end, RecurDateTime.DateTimePart.Day) > 0 ||
              RecurDateTime.Compare(last, to, RecurDateTime.DateTimePart.Day) > 0)
                return false;

            return true;
        }
Пример #7
0
        /// <summary>
        /// This is used to find the next instance of the daily frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <param name="last">This is used to pass in the last instance date calculated and return the next
        /// instance date</param>
        /// <returns>True if the recurrence has another instance or false if there are no more instances</returns>
        public bool FindNext(Recurrence r, RecurDateTime end, RecurDateTime to, RecurDateTime last)
        {
            last.AddDays(r.Interval);

            if (RecurDateTime.Compare(last, end, RecurDateTime.DateTimePart.Day) > 0 ||
                RecurDateTime.Compare(last, to, RecurDateTime.DateTimePart.Day) > 0)
            {
                return(false);
            }

            return(true);
        }
Пример #8
0
        /// <summary>
        /// This is used to expand by month day
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public static int ByMonthDay(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            int expIdx, monthDay, count = dates.Count;

            UniqueIntegerCollection byMonthDay = r.ByMonthDay;

            // Don't bother if either collection is empty
            if(count != 0 && byMonthDay.Count != 0)
                for(int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each month day specified
                    for(expIdx = 0; expIdx < byMonthDay.Count; expIdx++)
                    {
                        monthDay = byMonthDay[expIdx];
                        rdtNew = new RecurDateTime(rdt);
                        rdtNew.Day = 1;

                        // From start of month or end of month?
                        if(monthDay > 0)
                            rdtNew.AddDays(monthDay - 1);
                        else
                        {
                            rdtNew.AddMonths(1);
                            rdtNew.AddDays(monthDay);
                        }

                        // If not in the month, discard it
                        if(rdtNew.Month != rdt.Month)
                            continue;

                        dates.Add(rdtNew);
                    }
                }

            return dates.Count;
        }
Пример #9
0
        /// <summary>
        /// This is used to find the next instance of the weekly frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <param name="last">This is used to pass in the last instance date calculated and return the next
        /// instance date</param>
        /// <returns>True if the recurrence has another instance or false if there are no more instances</returns>
        public bool FindNext(Recurrence r, RecurDateTime end, RecurDateTime to, RecurDateTime last)
        {
            RecurDateTime rdtWeek;

            last.AddDays(r.Interval * 7);

            // For this one, compare the week start date
            rdtWeek = new RecurDateTime(last);
            rdtWeek.AddDays(0 - r.weekdayOffset);

            if(RecurDateTime.Compare(rdtWeek, end, RecurDateTime.DateTimePart.Day) > 0 ||
              RecurDateTime.Compare(rdtWeek, to, RecurDateTime.DateTimePart.Day) > 0)
                return false;

            return true;
        }
Пример #10
0
        /// <summary>
        /// This is used to find the next instance of the weekly frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <param name="last">This is used to pass in the last instance date calculated and return the next
        /// instance date</param>
        /// <returns>True if the recurrence has another instance or false if there are no more instances</returns>
        public bool FindNext(Recurrence r, RecurDateTime end, RecurDateTime to, RecurDateTime last)
        {
            RecurDateTime rdtWeek;

            last.AddDays(r.Interval * 7);

            // For this one, compare the week start date
            rdtWeek = new RecurDateTime(last);
            rdtWeek.AddDays(0 - r.weekdayOffset);

            if (RecurDateTime.Compare(rdtWeek, end, RecurDateTime.DateTimePart.Day) > 0 ||
                RecurDateTime.Compare(rdtWeek, to, RecurDateTime.DateTimePart.Day) > 0)
            {
                return(false);
            }

            return(true);
        }
Пример #11
0
        /// <summary>
        /// This is used to expand one or more weeks by day of the week
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public static int ByDayInWeeks(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            int           expIdx, count = dates.Count;

            DayInstanceCollection byDay = r.ByDay;

            // Don't bother if either collection is empty
            if (count != 0 && byDay.Count != 0)
            {
                for (int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // If not valid, discard it
                    if (!rdt.IsValidDate())
                    {
                        continue;
                    }

                    // Expand the date/time by adding a new entry for each day of the week.  As with filtering,
                    // the instance number is ignored as it isn't useful here.  For this, the "week" is the seven
                    // day period starting on the occurrence date.
                    for (expIdx = 0; expIdx < byDay.Count; expIdx++)
                    {
                        rdtNew = new RecurDateTime(rdt);
                        rdtNew.AddDays((((int)byDay[expIdx].DayOfWeek + 7 - (int)r.WeekStart) % 7) -
                                       (((int)rdt.DayOfWeek + 7 - (int)r.WeekStart) % 7));
                        dates.Add(rdtNew);
                    }
                }
            }

            return(dates.Count);
        }
Пример #12
0
        /// <summary>
        /// This is used to find the starting point for the daily frequency
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="start">The recurrence start date</param>
        /// <param name="end">The recurrence end date</param>
        /// <param name="from">The start date of the range limiting the instances generated</param>
        /// <param name="to">The end date of the range limiting the instances generated</param>
        /// <returns>The first instance date or null if there are no more instances</returns>
        public RecurDateTime FindStart(Recurrence r, RecurDateTime start, RecurDateTime end, RecurDateTime from,
          RecurDateTime to)
        {
            RecurDateTime rdt = new RecurDateTime(start);
            int adjust;

            // Get the difference between the recurrence start and the limiting range start
            DateTime dtStart = start.ToDateTime().Date, dtFrom = from.ToDateTime().Date;

            // Adjust the date so that it's in range
            if(dtStart < dtFrom)
            {
                TimeSpan ts = dtFrom - dtStart;

                adjust = ts.Days + r.Interval - 1;
                rdt.AddDays(adjust - (adjust % r.Interval));
            }

            if(RecurDateTime.Compare(rdt, end, RecurDateTime.DateTimePart.Day) > 0 ||
              RecurDateTime.Compare(rdt, to, RecurDateTime.DateTimePart.Day) > 0)
                return null;

            return rdt;
        }
Пример #13
0
        /// <summary>
        /// This is used to expand the yearly frequency by day of the week
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public int ByDay(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            DayOfWeek dow;

            int expIdx, instance, count = dates.Count;

            DayInstanceCollection byDay = r.ByDay;

            // Don't bother if either collection is empty
            if(count != 0 && byDay.Count != 0)
                for(int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each week day instance specified
                    for(expIdx = 0; expIdx < byDay.Count; expIdx++)
                    {
                        instance = byDay[expIdx].Instance;
                        dow = byDay[expIdx].DayOfWeek;

                        if(instance == 0)
                        {
                            // Expand to every specified day of the week in the year
                            rdtNew = new RecurDateTime(rdt);
                            rdtNew.Month = 0;
                            rdtNew.Day = 1;
                            rdtNew.AddDays(((int)dow + 7 - (int)rdtNew.DayOfWeek) % 7);

                            while(rdtNew.Year == rdt.Year)
                            {
                                dates.Add(new RecurDateTime(rdtNew));
                                rdtNew.AddDays(7);
                            }

                            continue;
                        }

                        if(instance > 0)
                        {
                            // Add the nth instance of the day of the week
                            rdtNew = new RecurDateTime(rdt);
                            rdtNew.Month = 0;
                            rdtNew.Day = 1;
                            rdtNew.AddDays((((int)dow + 7 - (int)rdtNew.DayOfWeek) % 7) + ((instance - 1) * 7));
                        }
                        else
                        {
                            // Add the nth instance of the day of the week from the end of the year
                            rdtNew = new RecurDateTime(rdt);
                            rdtNew.Month = 11;
                            rdtNew.Day = 31;
                            rdtNew.AddDays(0 - (((int)rdtNew.DayOfWeek + 7 - (int)dow) % 7) + ((instance + 1) * 7));
                        }

                        // If not in the year, discard it
                        if(rdtNew.Year != rdt.Year)
                            continue;

                        dates.Add(new RecurDateTime(rdtNew));
                    }
                }

            return dates.Count;
        }
Пример #14
0
        /// <summary>
        /// This is used to expand the yearly frequency by day of the week
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public int ByDay(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            DayOfWeek     dow;

            int expIdx, instance, count = dates.Count;

            DayInstanceCollection byDay = r.ByDay;

            // Don't bother if either collection is empty
            if (count != 0 && byDay.Count != 0)
            {
                for (int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each week day instance specified
                    for (expIdx = 0; expIdx < byDay.Count; expIdx++)
                    {
                        instance = byDay[expIdx].Instance;
                        dow      = byDay[expIdx].DayOfWeek;

                        if (instance == 0)
                        {
                            // Expand to every specified day of the week in the year
                            rdtNew = new RecurDateTime(rdt)
                            {
                                Month = 0, Day = 1
                            };
                            rdtNew.AddDays(((int)dow + 7 - (int)rdtNew.DayOfWeek) % 7);

                            while (rdtNew.Year == rdt.Year)
                            {
                                dates.Add(new RecurDateTime(rdtNew));
                                rdtNew.AddDays(7);
                            }

                            continue;
                        }

                        if (instance > 0)
                        {
                            // Add the nth instance of the day of the week
                            rdtNew = new RecurDateTime(rdt)
                            {
                                Month = 0, Day = 1
                            };
                            rdtNew.AddDays((((int)dow + 7 - (int)rdtNew.DayOfWeek) % 7) + ((instance - 1) * 7));
                        }
                        else
                        {
                            // Add the nth instance of the day of the week from the end of the year
                            rdtNew = new RecurDateTime(rdt)
                            {
                                Month = 11, Day = 31
                            };
                            rdtNew.AddDays(0 - (((int)rdtNew.DayOfWeek + 7 - (int)dow) % 7) + ((instance + 1) * 7));
                        }

                        // If not in the year, discard it
                        if (rdtNew.Year != rdt.Year)
                        {
                            continue;
                        }

                        dates.Add(new RecurDateTime(rdtNew));
                    }
                }
            }

            return(dates.Count);
        }
Пример #15
0
        /// <summary>
        /// This is used to expand one or more weeks by day of the week
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public static int ByDayInWeeks(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            int expIdx, count = dates.Count;

            DayInstanceCollection byDay = r.ByDay;

            // Don't bother if either collection is empty
            if(count != 0 && byDay.Count != 0)
                for(int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // If not valid, discard it
                    if(!rdt.IsValidDate())
                        continue;

                    // Expand the date/time by adding a new entry for each day of the week.  As with filtering,
                    // the instance number is ignored as it isn't useful here.  For this, the "week" is the seven
                    // day period starting on the occurrence date.
                    for(expIdx = 0; expIdx < byDay.Count; expIdx++)
                    {
                        rdtNew = new RecurDateTime(rdt);
                        rdtNew.AddDays((((int)byDay[expIdx].DayOfWeek + 7 - (int)r.WeekStart) % 7) -
                            (((int)rdt.DayOfWeek + 7 - (int)r.WeekStart) % 7));
                        dates.Add(rdtNew);
                    }
                }

            return dates.Count;
        }