/// <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); rdtNew.Month = 0; rdtNew.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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }