Example #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;
        }
Example #2
0
        /// <summary>
        /// This is used to expand the yearly frequency by month
        /// </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>This may generate invalid dates (i.e. June 31st).  These will be removed later.</remarks>
        public int ByMonth(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;

            int expIdx, count = dates.Count;

            UniqueIntegerCollection byMonth = r.ByMonth;

            // Don't bother if either collection is empty
            if (count != 0 && byMonth.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 specified
                    for (expIdx = 0; expIdx < byMonth.Count; expIdx++)
                    {
                        rdtNew = new RecurDateTime(rdt)
                        {
                            Month = byMonth[expIdx] - 1
                        };
                        dates.Add(rdtNew);
                    }
                }
            }

            return(dates.Count);
        }
Example #3
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);
        }
Example #4
0
        /// <summary>
        /// This is used to expand by second
        /// </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 a date in the collection is invalid, it will be discarded</remarks>
        public static int BySecond(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            int           expIdx, count = dates.Count;

            UniqueIntegerCollection bySecond = r.BySecond;

            // Don't bother if either collection is empty
            if (count != 0 && bySecond.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 second specified
                    for (expIdx = 0; expIdx < bySecond.Count; expIdx++)
                    {
                        rdtNew        = new RecurDateTime(rdt);
                        rdtNew.Second = bySecond[expIdx];
                        dates.Add(rdtNew);
                    }
                }
            }

            return(dates.Count);
        }
Example #5
0
        /// <summary>
        /// This is used to find the starting point for the secondly 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;

            if (RecurDateTime.Compare(start, from, RecurDateTime.DateTimePart.Hour) < 0)
            {
                // Get the difference between the recurrence start and the limiting range start
                DateTime dtStart = start.ToDateTime(), dtFrom = from.ToDateTime();

                // Adjust the date/time so that it's in range
                TimeSpan ts = dtFrom - dtStart;

                adjust = (int)ts.TotalSeconds + r.Interval - 1;
                rdt.AddSeconds(adjust - (adjust % r.Interval));
            }

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

            return(rdt);
        }
Example #6
0
        /// <summary>
        /// This is used to find the starting point for the minutely 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;

            if(RecurDateTime.Compare(start, from, RecurDateTime.DateTimePart.Hour) < 0)
            {
                // Get the difference between the recurrence start and the limiting range start
                DateTime dtStart = start.ToDateTime().AddSeconds(0 - start.Second),
                         dtFrom = from.ToDateTime().AddSeconds(0 - from.Second);

                // Adjust the date/time so that it's in range
                TimeSpan ts = dtFrom - dtStart;

                adjust = (int)ts.TotalMinutes + r.Interval - 1;
                rdt.AddMinutes(adjust - (adjust % r.Interval));
            }

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

            return rdt;
        }
Example #7
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);
        }
Example #8
0
        /// <summary>
        /// This is used to find the next instance of the yearly 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.Year += r.Interval;

            if(last.Year > end.Year || last.Year > to.Year)
                return false;

            return true;
        }
Example #9
0
        /// <summary>
        /// This is used to find the next instance of the secondly 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.AddSeconds(r.Interval);

            if(last > end || last > to)
                return false;

            return true;
        }
Example #10
0
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="rdt">The recurrence date/time to copy</param>
 public RecurDateTime(RecurDateTime rdt)
 {
     year   = rdt.Year;
     month  = rdt.Month;
     day    = rdt.Day;
     hour   = rdt.Hour;
     minute = rdt.Minute;
     second = rdt.Second;
 }
Example #11
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;
        }
Example #12
0
        /// <summary>
        /// This is used to find the next instance of the yearly 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.Year += r.Interval;

            if (last.Year > end.Year || last.Year > to.Year)
            {
                return(false);
            }

            return(true);
        }
Example #13
0
        /// <summary>
        /// This is used to find the next instance of the secondly 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.AddSeconds(r.Interval);

            if (last > end || last > to)
            {
                return(false);
            }

            return(true);
        }
Example #14
0
        //=====================================================================

        /// <summary>
        /// Compares this instance to a specified object and returns an indication of their relative values
        /// </summary>
        /// <param name="obj">An object to compare or null</param>
        /// <returns>Returns -1 if this instance is less than the value, 0 if they are equal, or 1 if this
        /// instance is greater than the value or the value is null.</returns>
        /// <exception cref="ArgumentException">This is thrown if the object to be compared is not a
        /// <c>RecurDateTime</c>.</exception>
        public int CompareTo(object obj)
        {
            RecurDateTime rd = obj as RecurDateTime;

            if (rd == null)
            {
                throw new ArgumentException(LR.GetString("ExRDTBadCompareObject"));
            }

            return(RecurDateTime.Compare(this, rd));
        }
Example #15
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);
        }
Example #16
0
        /// <summary>
        /// This is overridden to allow proper comparison of RecurDateTime objects
        /// </summary>
        /// <param name="obj">The object to which this instance is compared</param>
        /// <returns>Returns true if the object equals this instance, false if it does not</returns>
        public override bool Equals(object obj)
        {
            RecurDateTime r = obj as RecurDateTime;

            if (r == null)
            {
                return(false);
            }

            return(year == r.Year && month == r.Month && day == r.Day && hour == r.Hour && minute == r.Minute &&
                   second == r.Second);
        }
Example #17
0
        /// <summary>
        /// This is used to expand the yearly frequency by week number
        /// </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 ByWeekNo(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;

            int expIdx, week, yearWeeks, count = dates.Count;

            UniqueIntegerCollection byWeekNo = r.ByWeekNo;

            // Don't bother if either collection is empty
            if (count != 0 && byWeekNo.Count != 0)
            {
                for (int idx = 0; idx < count; idx++)
                {
                    rdt       = dates[0];
                    yearWeeks = DateUtils.WeeksInYear(rdt.Year, r.WeekStart);
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each week number specified
                    for (expIdx = 0; expIdx < byWeekNo.Count; expIdx++)
                    {
                        week = byWeekNo[expIdx];

                        // If not in the year, discard it
                        if ((week == 53 || week == -53) && yearWeeks == 52)
                        {
                            continue;
                        }

                        if (week > 0)
                        {
                            rdtNew = new RecurDateTime(DateUtils.DateFromWeek(rdt.Year, week, r.WeekStart,
                                                                              r.weekdayOffset));
                        }
                        else
                        {
                            rdtNew = new RecurDateTime(DateUtils.DateFromWeek(rdt.Year, yearWeeks + week + 1,
                                                                              r.WeekStart, r.weekdayOffset));
                        }

                        rdtNew.Hour   = rdt.Hour;
                        rdtNew.Minute = rdt.Minute;
                        rdtNew.Second = rdt.Second;

                        dates.Add(rdtNew);
                    }
                }
            }

            return(dates.Count);
        }
Example #18
0
        //=====================================================================

        /// <summary>
        /// Returns a value indicating whether two specified instances of RecurDateTime are equal
        /// </summary>
        /// <param name="r1">The first date/time to compare</param>
        /// <param name="r2">The second date/time to compare</param>
        /// <returns>Returns true if the date/times are equal, false if they are not</returns>
        public static bool Equals(RecurDateTime r1, RecurDateTime r2)
        {
            if ((object)r1 == null && (object)r2 == null)
            {
                return(true);
            }

            if ((object)r1 == null)
            {
                return(false);
            }

            return(r1.Equals(r2));
        }
Example #19
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);
        }
Example #20
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);
        }
Example #21
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;
        }
Example #22
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);
        }
Example #23
0
        /// <summary>
        /// This is used to find the starting point for the yearly 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)
        {
            int adjust;

            RecurDateTime rdt = new RecurDateTime(start);

            // Adjust the year if the starting date is before the limiting range start date
            if(rdt.Year < from.Year)
            {
                adjust = from.Year - rdt.Year + r.Interval - 1;
                rdt.Year += (adjust - (adjust % r.Interval));
            }

            if(rdt.Year > end.Year || rdt.Year > to.Year)
                return null;

            return rdt;
        }
Example #24
0
        /// <summary>
        /// This is used to find the starting point for the monthly 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)
        {
            int adjust;

            RecurDateTime rdt = new RecurDateTime(start);

            // Adjust the date if the starting date is before the limiting range start date
            if(RecurDateTime.Compare(rdt, from, RecurDateTime.DateTimePart.Month) < 0)
            {
                adjust = ((from.Year - rdt.Year) * 12) + from.Month - rdt.Month + r.Interval - 1;
                rdt.AddMonths(adjust - (adjust % r.Interval));
            }

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

            return rdt;
        }
Example #25
0
        /// <summary>
        /// This is used to find the starting point for the yearly 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)
        {
            int adjust;

            RecurDateTime rdt = new RecurDateTime(start);

            // Adjust the year if the starting date is before the limiting range start date
            if (rdt.Year < from.Year)
            {
                adjust    = from.Year - rdt.Year + r.Interval - 1;
                rdt.Year += (adjust - (adjust % r.Interval));
            }

            if (rdt.Year > end.Year || rdt.Year > to.Year)
            {
                return(null);
            }

            return(rdt);
        }
Example #26
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;
        }
Example #27
0
        /// <summary>
        /// This is used to find the starting point for the monthly 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)
        {
            int adjust;

            RecurDateTime rdt = new RecurDateTime(start);

            // Adjust the date if the starting date is before the limiting range start date
            if (RecurDateTime.Compare(rdt, from, RecurDateTime.DateTimePart.Month) < 0)
            {
                adjust = ((from.Year - rdt.Year) * 12) + from.Month - rdt.Month + r.Interval - 1;
                rdt.AddMonths(adjust - (adjust % r.Interval));
            }

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

            return(rdt);
        }
Example #28
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;
        }
Example #29
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);
        }
Example #30
0
        /// <summary>
        /// Compares two <c>RecurDateTime</c> values and returns an integer that indicates their relationship.
        /// This version only compares up to the specified date/time part.
        /// </summary>
        /// <param name="r1">The first date/time</param>
        /// <param name="r2">The second date/time</param>
        /// <param name="part">The part up to which comparisons are made.  Parts smaller than this are ignored.</param>
        /// <returns>Returns -1 if the first instance is less than the second, 0 if they are equal, or 1 if the
        /// first instance is greater than the second.</returns>
        public static int Compare(RecurDateTime r1, RecurDateTime r2, DateTimePart part)
        {
            // Cast as object for null checks or it goes recursive
            if ((object)r1 == null && (object)r2 == null)
            {
                return(0);
            }

            if ((object)r1 != null && (object)r2 == null)
            {
                return(1);
            }

            if ((object)r1 == null && (object)r2 != null)
            {
                return(-1);
            }

            if (r1.Year < r2.Year)
            {
                return(-1);
            }

            if (r1.Year > r2.Year)
            {
                return(1);
            }

            if (part == DateTimePart.Year)
            {
                return(0);
            }

            if (r1.Month < r2.Month)
            {
                return(-1);
            }

            if (r1.Month > r2.Month)
            {
                return(1);
            }

            if (part == DateTimePart.Month)
            {
                return(0);
            }

            if (r1.Day < r2.Day)
            {
                return(-1);
            }

            if (r1.Day > r2.Day)
            {
                return(1);
            }

            if (part == DateTimePart.Day)
            {
                return(0);
            }

            if (r1.Hour < r2.Hour)
            {
                return(-1);
            }

            if (r1.Hour > r2.Hour)
            {
                return(1);
            }

            if (part == DateTimePart.Hour)
            {
                return(0);
            }

            if (r1.Minute < r2.Minute)
            {
                return(-1);
            }

            if (r1.Minute > r2.Minute)
            {
                return(1);
            }

            if (part == DateTimePart.Minute)
            {
                return(0);
            }

            if (r1.Second < r2.Second)
            {
                return(-1);
            }

            if (r1.Second > r2.Second)
            {
                return(1);
            }

            return(0);
        }
Example #31
0
        /// <summary>
        /// This is used to expand by second
        /// </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 a date in the collection is invalid, it will be discarded</remarks>
        public static int BySecond(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            int expIdx, count = dates.Count;

            UniqueIntegerCollection bySecond = r.BySecond;

            // Don't bother if either collection is empty
            if(count != 0 && bySecond.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 second specified
                    for(expIdx = 0; expIdx < bySecond.Count; expIdx++)
                    {
                        rdtNew = new RecurDateTime(rdt);
                        rdtNew.Second = bySecond[expIdx];
                        dates.Add(rdtNew);
                    }
                }

            return dates.Count;
        }
Example #32
0
        /// <summary>
        /// This method is used to return all recurring instances between the two specified date/times based on
        /// the current settings.
        /// </summary>
        /// <param name="fromDate">The minimum date/time on or after which instances should occur.</param>
        /// <param name="toDate">The maximum date/time on or before which instances should occur.</param>
        /// <returns>Returns a <see cref="DateTimeCollection"/> of <see cref="DateTime" /> objects that represent
        /// the instances found between the two specified date/times.</returns>
        private DateTimeCollection GenerateInstances(DateTime fromDate, DateTime toDate)
        {
            RecurDateTimeCollection rdtc;
            RecurDateTime rdt;
            int idx, count, lastYear = -1;

            DateTimeCollection dcDates = new DateTimeCollection();

            // If undefined or if the requested range is outside that of the recurrence, don't bother.  Just
            // return an empty collection.  Note that for defined recurrences that use a count, we'll always
            // have to expand it.
            if(frequency == RecurFrequency.Undefined || startDate > toDate || untilDate < fromDate)
                return dcDates;

            RecurDateTime start = new RecurDateTime(startDate), end = new RecurDateTime(untilDate),
                from = new RecurDateTime(fromDate), to = new RecurDateTime(toDate);

            RecurDateTime current = freqRules.FindStart(this, start, end, from, to);

            // If there's nothing to generate, stop now
            if(current == null)
                return dcDates;

            rdtc = new RecurDateTimeCollection();

            // Initialize the filtering arrays.  These help speed up the filtering process by letting us do one
            // look up as opposed to comparing all elements in the collection.
            Array.Clear(isSecondUsed, 0, isSecondUsed.Length);
            Array.Clear(isMinuteUsed, 0, isMinuteUsed.Length);
            Array.Clear(isHourUsed, 0, isHourUsed.Length);
            Array.Clear(isDayUsed, 0, isDayUsed.Length);
            Array.Clear(isMonthDayUsed, 0, isMonthDayUsed.Length);
            Array.Clear(isNegMonthDayUsed, 0, isNegMonthDayUsed.Length);
            Array.Clear(isYearDayUsed, 0, isYearDayUsed.Length);
            Array.Clear(isNegYearDayUsed, 0, isNegYearDayUsed.Length);
            Array.Clear(isMonthUsed, 0, isMonthUsed.Length);

            if(bySecond.Count != 0)
                foreach(int second in bySecond)
                    isSecondUsed[second] = true;

            if(byMinute.Count != 0)
                foreach(int minute in byMinute)
                    isMinuteUsed[minute] = true;

            if(byHour.Count != 0)
                foreach(int hour in byHour)
                    isHourUsed[hour] = true;

            if(byMonth.Count != 0)
                foreach(int month in byMonth)
                    isMonthUsed[month - 1] = true;

            // When filtering, the instance is ignored
            if(byDay.Count != 0)
                foreach(DayInstance di in byDay)
                    isDayUsed[(int)di.DayOfWeek] = true;

            // Negative days are from the end of the month
            if(byMonthDay.Count != 0)
                foreach(int monthDay in byMonthDay)
                    if(monthDay > 0)
                        isMonthDayUsed[monthDay] = true;
                    else
                        isNegMonthDayUsed[0 - monthDay] = true;

            // Negative days are from the end of the year
            if(byYearDay.Count != 0)
                foreach(int yearDay in byYearDay)
                    if(yearDay > 0)
                        isYearDayUsed[yearDay] = true;
                    else
                        isNegYearDayUsed[0 - yearDay] = true;

            do
            {
                rdtc.Clear();
                rdtc.Add(current);

                // The spec is rather vague about how some of the rules are used together.  For example, it says
                // that rule parts for a period of time less than the frequency generally expand it.  However,
                // an example for the MONTHLY frequency shows that when BYMONTHDAY and BYDAY are used together,
                // BYDAY acts as a filter for BYMONTHDAY not an expansion of the frequency.  When used by
                // themselves, the rules in question do act as expansions.  There are no examples for the yearly
                // frequency that show how all of the various combinations interact so I'm making some
                // assumptions based on an evaluation of what makes the most sense.
                switch(frequency)
                {
                    case RecurFrequency.Yearly:
                        // This one gets rather messy so it's separate
                        ExpandYearly(rdtc);
                        break;

                    case RecurFrequency.Monthly:
                        if(freqRules.ByMonth(this, rdtc) != 0)
                            if(freqRules.ByYearDay(this, rdtc) != 0)
                            {
                                // If BYMONTHDAY and BYDAY are specified, expand by month day and filter by day.
                                // If one but not the other or neither is specified, handle them in order as
                                // usual.
                                if(byMonthDay.Count != 0 && byDay.Count != 0)
                                {
                                    if(Expand.ByMonthDay(this, rdtc) != 0)
                                        if(Filter.ByDay(this, rdtc) != 0)
                                        {
                                            // These always expand if used
                                            Expand.ByHour(this, rdtc);
                                            Expand.ByMinute(this, rdtc);
                                            Expand.BySecond(this, rdtc);
                                        }
                                }
                                else
                                    if(Expand.ByMonthDay(this, rdtc) != 0)
                                        if(freqRules.ByDay(this, rdtc) != 0)
                                        {
                                            // These always expand if used
                                            Expand.ByHour(this, rdtc);
                                            Expand.ByMinute(this, rdtc);
                                            Expand.BySecond(this, rdtc);
                                        }
                            }
                        break;

                    default:
                        // Everything else is fairly straightforward.  We just expand or filter based on the
                        // frequency type and what rules are specified.
                        if(freqRules.ByMonth(this, rdtc) != 0)
                            if(freqRules.ByYearDay(this, rdtc) != 0)
                                if(freqRules.ByMonthDay(this, rdtc) != 0)
                                    if(freqRules.ByDay(this, rdtc) != 0)
                                        if(freqRules.ByHour(this, rdtc) != 0)
                                            if(freqRules.ByMinute(this, rdtc) != 0)
                                                freqRules.BySecond(this, rdtc);
                        break;
                }

                // Sort the dates and remove invalid and duplicate dates
                rdtc.Sort();

                for(idx = 0, count = rdtc.Count; idx < count; idx++)
                {
                    rdt = rdtc[idx];

                    // If not valid, discard it.
                    if(!rdt.IsValidDate())
                    {
                        rdtc.RemoveAt(idx);
                        idx--;
                        count--;
                        continue;
                    }

                    // Discard it if it falls on a holiday
                    if(!canOccurOnHoliday)
                    {
                        // If this is the first call or the year changes, get the holidays in the date's year
                        // and the next year.
                        if(holDates == null || lastYear != rdt.Year)
                        {
                            holDates = new HashSet<DateTime>(holidays.HolidaysBetween(rdt.Year, rdt.Year + 1));
                            lastYear = rdt.Year;
                        }

                        // Note that we only compare the date part as the holiday's time probably will not match
                        // the recurrence's time.
                        if(holDates.Contains(rdt.ToDateTime().Date))
                        {
                            rdtc.RemoveAt(idx);
                            idx--;
                            count--;
                            continue;
                        }
                    }

                    // Discard it if it's a duplicate
                    if(idx != 0 && rdt == rdtc[idx - 1])
                    {
                        rdtc.RemoveAt(idx);
                        idx--;
                        count--;
                        continue;
                    }
                }

                if(rdtc.Count != 0)
                {
                    // Apply the BYSETPOS rule and remove entries prior to the start or past the end of the
                    // ranges.
                    if(bySetPos.Count != 0)
                    {
                        foreach(int nPos in bySetPos)
                        {
                            // Invert negative values.  They'll select elements indexed from the end of the
                            // array.
                            if(nPos < 0)
                                idx = nPos + rdtc.Count;
                            else
                                idx = nPos - 1;

                            if(idx >= 0 && idx < rdtc.Count)
                                if(rdtc[idx] >= start && rdtc[idx] <= end && rdtc[idx] >= from && rdtc[idx] <= to)
                                    dcDates.Add(rdtc[idx].ToDateTime());
                        }
                    }
                    else
                        for(idx = 0; idx < rdtc.Count; idx++)
                            if(rdtc[idx] >= start && rdtc[idx] <= end && rdtc[idx] >= from && rdtc[idx] <= to)
                                dcDates.Add(rdtc[idx].ToDateTime());

                    // Handle MaxOccurrences property.  Note that if it's used, it is assumed that the limiting
                    // range starts at the recurrence start.  Otherwise, we have no way of knowing how many
                    // occurred between the recurrence start and the limiting range's start date.
                    if(maxOccur != 0 && dcDates.Count > maxOccur)
                        dcDates.RemoveRange(maxOccur, dcDates.Count - maxOccur);
                }

                // Loop until the end of the recurrence or the range
            } while(freqRules.FindNext(this, end, to, current) && (maxOccur == 0 || dcDates.Count < maxOccur));

            // Sort the collection one last time.  There's no guaranteed order of selection if BYSETPOS was used.
            dcDates.Sort(true);

            return dcDates;
        }
Example #33
0
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="rdt">The recurrence date/time to copy</param>
 public RecurDateTime(RecurDateTime rdt)
 {
     year = rdt.Year;
     month = rdt.Month;
     day = rdt.Day;
     hour = rdt.Hour;
     minute = rdt.Minute;
     second = rdt.Second;
 }
Example #34
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;
        }
Example #35
0
        /// <summary>
        /// This is used to expand the yearly frequency by week number
        /// </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 ByWeekNo(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;

            int expIdx, week, yearWeeks, count = dates.Count;

            UniqueIntegerCollection byWeekNo = r.ByWeekNo;

            // Don't bother if either collection is empty
            if(count != 0 && byWeekNo.Count != 0)
                for(int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    yearWeeks = DateUtils.WeeksInYear(rdt.Year, r.WeekStart);
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each week number specified
                    for(expIdx = 0; expIdx < byWeekNo.Count; expIdx++)
                    {
                        week = byWeekNo[expIdx];

                        // If not in the year, discard it
                        if((week == 53 || week == -53) && yearWeeks == 52)
                            continue;

                        if(week > 0)
                        {
                            rdtNew = new RecurDateTime(DateUtils.DateFromWeek(rdt.Year, week, r.WeekStart,
                                r.weekdayOffset));
                        }
                        else
                            rdtNew = new RecurDateTime(DateUtils.DateFromWeek(rdt.Year, yearWeeks + week + 1,
                                r.WeekStart, r.weekdayOffset));

                        rdtNew.Hour = rdt.Hour;
                        rdtNew.Minute = rdt.Minute;
                        rdtNew.Second = rdt.Second;

                        dates.Add(rdtNew);
                    }
                }

            return dates.Count;
        }
Example #36
0
        //=====================================================================

        /// <summary>
        /// Returns a value indicating whether two specified instances of RecurDateTime are equal
        /// </summary>
        /// <param name="r1">The first date/time to compare</param>
        /// <param name="r2">The second date/time to compare</param>
        /// <returns>Returns true if the date/times are equal, false if they are not</returns>
        public static bool Equals(RecurDateTime r1, RecurDateTime r2)
        {
            if((object)r1 == null && (object)r2 == null)
                return true;

            if((object)r1 == null)
                return false;

            return r1.Equals(r2);
        }
Example #37
0
        /// <summary>
        /// Compares two <c>RecurDateTime</c> values and returns an integer that indicates their relationship.
        /// This version only compares up to the specified date/time part.
        /// </summary>
        /// <param name="r1">The first date/time</param>
        /// <param name="r2">The second date/time</param>
        /// <param name="part">The part up to which comparisons are made.  Parts smaller than this are ignored.</param>
        /// <returns>Returns -1 if the first instance is less than the second, 0 if they are equal, or 1 if the
        /// first instance is greater than the second.</returns>
        public static int Compare(RecurDateTime r1, RecurDateTime r2, DateTimePart part)
        {
            // Cast as object for null checks or it goes recursive
            if((object)r1 == null && (object)r2 == null)
                return 0;

            if((object)r1 != null && (object)r2 == null)
                return 1;

            if((object)r1 == null && (object)r2 != null)
                return -1;

            if(r1.Year < r2.Year)
                return -1;

            if(r1.Year > r2.Year)
                return 1;

            if(part == DateTimePart.Year)
                return 0;

            if(r1.Month < r2.Month)
                return -1;

            if(r1.Month > r2.Month)
                return 1;

            if(part == DateTimePart.Month)
                return 0;

            if(r1.Day < r2.Day)
                return -1;

            if(r1.Day > r2.Day)
                return 1;

            if(part == DateTimePart.Day)
                return 0;

            if(r1.Hour < r2.Hour)
                return -1;

            if(r1.Hour > r2.Hour)
                return 1;

            if(part == DateTimePart.Hour)
                return 0;

            if(r1.Minute < r2.Minute)
                return -1;

            if(r1.Minute > r2.Minute)
                return 1;

            if(part == DateTimePart.Minute)
                return 0;

            if(r1.Second < r2.Second)
                return -1;

            if(r1.Second > r2.Second)
                return 1;

            return 0;
        }
Example #38
0
        /// <summary>
        /// This is used to expand the yearly frequency by month
        /// </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>This may generate invalid dates (i.e. June 31st).  These will be removed later.</remarks>
        public int ByMonth(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;

            int expIdx, count = dates.Count;

            UniqueIntegerCollection byMonth = r.ByMonth;

            // Don't bother if either collection is empty
            if(count != 0 && byMonth.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 specified
                    for(expIdx = 0; expIdx < byMonth.Count; expIdx++)
                    {
                        rdtNew = new RecurDateTime(rdt);
                        rdtNew.Month = byMonth[expIdx] - 1;
                        dates.Add(rdtNew);
                    }
                }

            return dates.Count;
        }
Example #39
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);
        }
Example #40
0
 /// <summary>
 /// Overload for greater than or equal operator
 /// </summary>
 /// <param name="r1">The first date/time object</param>
 /// <param name="r2">The second date/time object</param>
 /// <returns>True if r1 is greater than or equal to r2, false if not</returns>
 public static bool operator >=(RecurDateTime r1, RecurDateTime r2)
 {
     return(RecurDateTime.Compare(r1, r2) >= 0);
 }
Example #41
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;
        }