/// <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 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; }
/// <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; }
//===================================================================== /// <summary> /// Test the recurrence class with the entered pattern /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void btnTest_Click(object sender, EventArgs e) { DateTimeCollection dc; int start, count; double elapsed; try { lblCount.Text = String.Empty; // Define the recurrence rule by parsing the text Recurrence r = new Recurrence(txtRRULE.Text); r.StartDateTime = dtpStartDate.Value; // Get the currently defined set of holidays if necessary if(!r.CanOccurOnHoliday) { Recurrence.Holidays.Clear(); Recurrence.Holidays.AddRange(hmHolidays.Holidays); } // For hourly, minutely, and secondly, warn the user if there is no end date or max occurrences if(r.Frequency >= RecurFrequency.Hourly && r.MaximumOccurrences == 0 && r.RecurUntil > r.StartDateTime.AddDays(100)) if(MessageBox.Show("This recurrence may run for a very long time. Continue?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.No) return; lbDates.DataSource = null; this.Cursor = Cursors.WaitCursor; start = System.Environment.TickCount; dc = r.InstancesBetween(r.StartDateTime, DateTime.MaxValue); elapsed = (System.Environment.TickCount - start) / 1000.0; count = dc.Count; if(count > 5000) { dc.RemoveRange(5000, count - 5000); lblCount.Text += "A large number of dates were returned. Only the first 5000 have been " + "loaded into the list box.\r\n"; } // DateTimeCollection is bindable so we can assign it as the list box's data source lbDates.DataSource = dc; lblCount.Text += String.Format("Found {0:N0} instances in {1:N2} seconds ({2:N2} instances/second)", count, elapsed, count / elapsed); } catch(Exception ex) { MessageBox.Show(ex.ToString()); } finally { this.Cursor = Cursors.Default; } }
/// <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; }
/// <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; }
/// <summary> /// Generate instances based on the settings in the pattern control /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event parameters</param> protected void btnTestPattern_Click(object sender, EventArgs e) { Recurrence r = new Recurrence(); rpRecurrence.GetRecurrence(r); // Make the textbox match the pattern control and use it's event handler txtRRULE.Text = r.ToString(); btnTest_Click(sender, e); }
/// <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 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; }
protected void Page_Load(object sender, EventArgs e) { this.Page.Title = "Recurrence Demo"; // On first load, set some defaults and bind the holiday list box to the defined recurrence holidays if(!Page.IsPostBack) { txtStartDate.Text = new DateTime(DateTime.Today.Year, 1, 1).ToString("G"); txtRRULE.Text = "FREQ=DAILY;INTERVAL=5;COUNT=50"; lbResults.DataTextFormatString = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + " " + CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern; Recurrence r = new Recurrence(txtRRULE.Text); rpRecurrence.SetRecurrence(r); lblDescription.Text = r.ToDescription(); lbHolidays.DataSource = Recurrence.Holidays; lbHolidays.DataBind(); } }
/// <summary> /// Use some limitations to prevent overloading the server or timing out the page if possible /// </summary> /// <param name="ro">The recurring object</param> /// <param name="r">The recurrence to check</param> private void ApplyLimits(RecurringObject ro, Recurrence r) { if(r.Frequency > RecurFrequency.Hourly) r.MaximumOccurrences = 5000; if(r.MaximumOccurrences != 0) { if(r.MaximumOccurrences > 5000) r.MaximumOccurrences = 5000; } else if(r.Frequency == RecurFrequency.Hourly) { if(r.RecurUntil > ro.StartDateTime.DateTimeValue.AddYears(5)) r.RecurUntil = ro.StartDateTime.DateTimeValue.AddYears(5); } else if(r.RecurUntil > ro.StartDateTime.DateTimeValue.AddYears(50)) r.RecurUntil = ro.StartDateTime.DateTimeValue.AddYears(50); }
/// <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; }
/// <summary> /// This is used to filter 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> public static int ByMonth(Recurrence r, RecurDateTimeCollection dates) { int count = dates.Count; // Don't bother if either collection is empty if(count != 0 && r.ByMonth.Count != 0) for(int idx = 0, collIdx = 0; idx < count; idx++) { // Remove the date/time if the month isn't wanted if(!r.isMonthUsed[dates[collIdx].Month]) { dates.RemoveAt(collIdx); count--; idx--; } else collIdx++; } return dates.Count; }
/// <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; }
/// <summary> /// This is used to filter 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 a date in the collection is invalid, it will be discarded</remarks> public static int ByYearDay(Recurrence r, RecurDateTimeCollection dates) { RecurDateTime rdt; int days, count = dates.Count; // Don't bother if either collection is empty if(count != 0 && r.ByYearDay.Count != 0) for(int idx = 0, collIdx = 0; idx < count; idx++) { rdt = dates[collIdx]; // If not valid, discard it if(!rdt.IsValidDate()) { dates.RemoveAt(collIdx); count--; idx--; continue; } days = (DateTime.IsLeapYear(rdt.Year)) ? 367 : 366; // Remove the date/time if the year day isn't wanted. Check both from the start of the year // and from the end of the year. if(!r.isYearDayUsed[rdt.DayOfYear] && !r.isNegYearDayUsed[days - rdt.DayOfYear]) { dates.RemoveAt(collIdx); count--; idx--; } else collIdx++; } 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; }
static void Main() { Recurrence r = new Recurrence(); int idx; Console.WriteLine("The first part will calculate instances using only the Recurrence class. All " + "instances are expressed in local time.\nPress ENTER to continue..."); Console.ReadLine(); // NOTE: The examples in the spec assume the US-Eastern time zone. Here, we're specifying the // date/times directly and everything is in local time. The recurrence engine always generates the // date/times in local time when used by itself. For time zone support, use the calendar objects as // demonstrated later on below. Console.WriteLine("Daily for 10 occurrences:"); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.MaximumOccurrences = 10; Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Daily until December 24, 1997:"); // We'll re-use the same object. Just reset it first. r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; // Note that in the spec examples, it looks as if the end times are wrong. It shows the times in // Universal Time as it should be but if you convert the times from Universal Time to US-Eastern time // (-05:00), it cuts a few of the patterns off too early. I've adjusted those where needed. r.RecurUntil = new DateTime(1997, 12, 24, 0, 0, 0); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other day - forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.Interval = 2; Console.WriteLine(r.ToStringWithStartDateTime()); // We'll limit the output of the "forever" rules by using the InstancesBetween() method to limit the // output to a range of dates and enumerate the returned DateTimeCollection. foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1997, 12, 5))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 10 days, 5 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.Interval = 10; r.MaximumOccurrences = 5; Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every day in January, for 3 years:"); r.Reset(); r.StartDateTime = new DateTime(1998, 1, 1, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.RecurUntil = new DateTime(2000, 1, 31, 9, 0, 0); r.ByMonth.Add(1); // When adding days without an instance value, you can use the helper method on the collection that // takes an array of DayOfWeek values rather than constructing an array of DayInstance objects. r.ByDay.AddRange(new[] { DayOfWeek.Sunday, DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // Like the last one but using a DAILY frequency Console.WriteLine("Everyday in January, for 3 years:"); r.Reset(); r.StartDateTime = new DateTime(1998, 1, 1, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.RecurUntil = new DateTime(2000, 1, 31, 9, 0, 0); r.ByMonth.Add(1); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Weekly for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.MaximumOccurrences = 10; Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Weekly until December 24, 1997:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.RecurUntil = new DateTime(1997, 12, 24, 0, 0, 0); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other week - forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.WeekStart = DayOfWeek.Sunday; Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1999, 2, 10))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Weekly on Tuesday and Thursday for 5 weeks:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.RecurUntil = new DateTime(1997, 10, 07, 0, 0, 0); r.WeekStart = DayOfWeek.Sunday; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Thursday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // Like the last one but using a count Console.WriteLine("Weekly on Tuesday and Thursday for 5 weeks:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.MaximumOccurrences = 10; r.WeekStart = DayOfWeek.Sunday; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Thursday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // NOTE: The inclusion of DTSTART in a recurrence set is a feature of the calendar objects, NOT the // recurrence engine. To include DTSTART, use a calendar object such as VEvent to generate the set // as demonstrated later on below. Console.WriteLine("Every other week on Monday, Wednesday and Friday until December 24, 1997, but " + "starting on Tuesday, September 2, 1997:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.WeekStart = DayOfWeek.Sunday; r.RecurUntil = new DateTime(1997, 12, 24, 0, 0, 0); r.ByDay.AddRange(new[] { DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other week on Tuesday and Thursday, for 8 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.WeekStart = DayOfWeek.Sunday; r.MaximumOccurrences = 8; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Thursday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the 1st Friday for ten occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 5, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 10; // There are also helper methods to add single instances r.ByDay.Add(1, DayOfWeek.Friday); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the 1st Friday until December 24, 1997:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 5, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.RecurUntil = new DateTime(1997, 12, 24, 0, 0, 0); r.ByDay.Add(1, DayOfWeek.Friday); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other month on the 1st and last Sunday of the month for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 7, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.Interval = 2; r.MaximumOccurrences = 10; r.ByDay.AddRange(new[] { new DayInstance(1, DayOfWeek.Sunday), new DayInstance(-1, DayOfWeek.Sunday) }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the second to last Monday of the month for 6 months:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 22, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 6; r.ByDay.Add(-2, DayOfWeek.Monday); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the third to the last day of the month, forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 28, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.ByMonthDay.Add(-3); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1998, 2, 28))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the 2nd and 15th of the month for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 10; r.ByMonthDay.AddRange(new[] { 2, 15 }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the first and last day of the month for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 30, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 10; r.ByMonthDay.AddRange(new[] { 1, -1 }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 18 months on the 10th through 15th of the month for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 10, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.Interval = 18; r.MaximumOccurrences = 10; r.ByMonthDay.AddRange(new[] { 10, 11, 12, 13, 14, 15 }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Tuesday, every other month:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.Interval = 2; r.ByDay.Add(DayOfWeek.Tuesday); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1998, 4, 1))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Yearly in June and July for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 6, 10, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.MaximumOccurrences = 10; r.ByMonth.AddRange(new[] { 6, 7 }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other year in January, February, and March for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 3, 10, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.Interval = 2; r.MaximumOccurrences = 10; r.ByMonth.AddRange(new[] { 1, 2, 3 }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 3rd year on the 1st, 100th and 200th day for 10 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 1, 1, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.Interval = 3; r.MaximumOccurrences = 10; r.ByYearDay.AddRange(new[] { 1, 100, 200 }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 20th Monday of the year, forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 5, 19, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByDay.Add(20, DayOfWeek.Monday); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(2004, 5, 19))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monday of week number 20 (where the default start of the week is Monday), forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 5, 12, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByWeekNo.Add(20); r.ByDay.Add(DayOfWeek.Monday); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(2004, 5, 19))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Thursday in March, forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 3, 13, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByMonth.Add(3); r.ByDay.Add(DayOfWeek.Thursday); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1999, 4, 1))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Thursday, but only during June, July, and August, forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 6, 5, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByMonth.AddRange(new[] { 6, 7, 8 }); r.ByDay.Add(DayOfWeek.Thursday); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1999, 9, 1))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Friday the 13th, forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.ByDay.Add(DayOfWeek.Friday); r.ByMonthDay.Add(13); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(2003, 12, 31))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("The first Saturday that follows the first Sunday of the month, forever:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 13, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.ByDay.Add(DayOfWeek.Saturday); r.ByMonthDay.AddRange(new[] { 7, 8, 9, 10, 11, 12, 13 }); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1998, 7, 1))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every four years, the first Tuesday after a Monday in November, forever " + "(U.S. Presidential Election day):"); r.Reset(); r.StartDateTime = new DateTime(1996, 11, 5, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.Interval = 4; r.ByMonth.Add(11); r.ByDay.Add(DayOfWeek.Tuesday); r.ByMonthDay.AddRange(new[] { 2, 3, 4, 5, 6, 7, 8 }); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(2004, 11, 3))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("The 3rd instance into the month of one of Tuesday, Wednesday or Thursday, for " + "the next 3 months:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 4, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 3; r.BySetPos.Add(3); r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("The 2nd to last weekday of the month:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 29, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.BySetPos.Add(-2); r.ByDay.AddRange(new[] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1998, 9, 29))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 3 hours from 9:00 AM to 5:00 PM on a specific day:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Hourly; r.Interval = 3; r.RecurUntil = new DateTime(1997, 9, 2, 17, 0, 0); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 15 minutes for 6 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Minutely; r.Interval = 15; r.MaximumOccurrences = 6; Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every hour and a half for 4 occurrences:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Minutely; r.Interval = 90; r.MaximumOccurrences = 4; Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 20 minutes from 9:00 AM to 4:40 PM every day:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.ByHour.AddRange(new[] { 9, 10, 11, 12, 13, 14, 15, 16 }); r.ByMinute.AddRange( new[] { 0, 20, 40 }); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1997, 9, 4))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // Like the last one but with a MINUTELY frequency Console.WriteLine("Every 20 minutes from 9:00 AM to 4:40 PM every day:"); r.Reset(); r.StartDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Minutely; r.Interval = 20; r.ByHour.AddRange(new[] { 9, 10, 11, 12, 13, 14, 15, 16 }); Console.WriteLine(r.ToStringWithStartDateTime()); // Not forever for the test foreach(DateTime dt in r.InstancesBetween(r.StartDateTime, new DateTime(1997, 9, 4))) Console.WriteLine(dt); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("An example where the days generated makes a difference because of WKST:"); r.Reset(); r.StartDateTime = new DateTime(1997, 8, 5, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.MaximumOccurrences = 4; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Sunday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Changing only WKST from the default MO to SU yields different results:"); r.Reset(); r.StartDateTime = new DateTime(1997, 8, 5, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.MaximumOccurrences = 4; r.WeekStart = DayOfWeek.Sunday; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Sunday }); Console.WriteLine(r.ToStringWithStartDateTime()); foreach(DateTime dt in r) Console.WriteLine(dt); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // Now do the same one but use the calendar classes to demonstrate the time zone abilities Console.WriteLine("\n\nThe next part will calculate instances using the calendar classes with " + "time zone support.\nPress ENTER to continue..."); Console.ReadLine(); // First, set up the time zone information. If you don't care about the time zone, you can skip this // stuff and everything will be calculated in local time. VTimeZone vtz = new VTimeZone(); vtz.TimeZoneId.Value = "US-Eastern"; // Set the standard time observance rule ObservanceRule obr = vtz.ObservanceRules.Add(ObservanceRuleType.Standard); obr.StartDateTime.DateTimeValue = new DateTime(1970, 10, 25, 2, 0, 0); obr.OffsetFrom.TimeSpanValue = TimeSpan.FromHours(-4); obr.OffsetTo.TimeSpanValue = TimeSpan.FromHours(-5); RRuleProperty rrule = new RRuleProperty(); rrule.Recurrence.RecurYearly(DayOccurrence.Last, DaysOfWeek.Sunday, 10, 1); obr.RecurrenceRules.Add(rrule); obr.TimeZoneNames.Add("Eastern Standard Time"); // Set the daylight saving time observance rule obr = vtz.ObservanceRules.Add(ObservanceRuleType.Daylight); obr.StartDateTime.DateTimeValue = new DateTime(1970, 4, 5, 2, 0, 0); obr.OffsetFrom.TimeSpanValue = TimeSpan.FromHours(-5); obr.OffsetTo.TimeSpanValue = TimeSpan.FromHours(-4); rrule = new RRuleProperty(); rrule.Recurrence.RecurYearly(DayOccurrence.First, DaysOfWeek.Sunday, 4, 1); obr.RecurrenceRules.Add(rrule); obr.TimeZoneNames.Add("Eastern Daylight Time"); VCalendar.TimeZones.Add(vtz); // Now we'll set up an event to use for the calculations. We don't need a VCalendar object as we are // just generating recurring instances. VEvent vevent = new VEvent(); // Add an RRULE property rrule = new RRuleProperty(); vevent.RecurrenceRules.Add(rrule); // Get a reference to the recurrence rule property's recurrence and the event's start date property // for convenience. r = rrule.Recurrence; StartDateProperty startDateTime = vevent.StartDateTime; // Set the time zone of the event's start date to the same ID used for the time zone component above vevent.StartDateTime.TimeZoneId = "US-Eastern"; //----------------------------------------------------------------- Console.WriteLine("Daily for 10 occurrences:"); // The start date is set on the event. We use the TimeZoneDateTime property to indicate that the // date/time is in the time zone. Using DateTimeValue instead would convert the value from local // time to the time zone. startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.MaximumOccurrences = 10; // Get the instances expressed in the time zone's time and in local time DateTimeInstanceCollection dtiTZ = vevent.AllInstances(false); DateTimeInstanceCollection dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); // We'll just display the start time from each instance. End time and duration info is also present // in the returned instances. for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Daily until December 24, 1997:"); // We'll re-use the same recurrence object. Just reset it first. r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; // Note that the recurrence rules in an event determine the end date of the event, NOT the EndDate // (DTEND) property of the event. The end date property on the event simply determines the duration // of each instance. Another thing to remember is that RecurUntil is specified in Universal Time // which ends up in local time when recurrence instances are generated. If specify times in another // time zone, be sure to set the RecurUntil time as a time in that time zone. r.RecurUntil = new DateTime(1997, 12, 24, 5, 0, 0).ToLocalTime(); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other day - forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.Interval = 2; // We'll limit the output of the "forever" rules by using the InstancesBetween() method to limit the // output to a range of dates and enumerate the returned DateTimeCollection. dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1997, 12, 5), false); // For local time, the start and end date must be in local time. To match the range in the prior // call, we use the DateTimeValue property of the start date property and convert a value in // Universal Time to local time. dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1997, 12, 5, 5, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 10 days, 5 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.Interval = 10; r.MaximumOccurrences = 5; dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Everyday in January, for 3 years:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1998, 1, 1, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.RecurUntil = new DateTime(2000, 1, 31, 14, 0, 0).ToLocalTime(); r.ByMonth.Add(1); // When adding days without an instance value, you can use the helper method on the collection that // takes an array of DayOfWeek values rather than constructing an array of DayInstance objects. r.ByDay.AddRange(new[] { DayOfWeek.Sunday, DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // Like the last one but using a DAILY frequency Console.WriteLine("Everyday in January, for 3 years:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1998, 1, 1, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.RecurUntil = new DateTime(2000, 1, 31, 14, 0, 0).ToLocalTime(); r.ByMonth.Add(1); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Weekly for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.MaximumOccurrences = 10; dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Weekly until December 24, 1997:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.RecurUntil = new DateTime(1997, 12, 24, 5, 0, 0).ToLocalTime(); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other week - forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.WeekStart = DayOfWeek.Sunday; // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1999, 2, 10), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1999, 2, 10, 5, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Weekly on Tuesday and Thursday for 5 weeks:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.RecurUntil = new DateTime(1997, 10, 07, 4, 0, 0).ToLocalTime(); r.WeekStart = DayOfWeek.Sunday; r.ByDay.AddRange(new [] { DayOfWeek.Tuesday, DayOfWeek.Thursday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // Like the last one but using a count Console.WriteLine("Weekly on Tuesday and Thursday for 5 weeks:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.MaximumOccurrences = 10; r.WeekStart = DayOfWeek.Sunday; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Thursday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // The inclusion of DTSTART in a recurrence set is a feature of the calendar objects, NOT the // recurrence engine. So, for this example, the start date will be included. Console.WriteLine("Every other week on Monday, Wednesday and Friday until December 24, 1997, but " + "starting on Tuesday, September 2, 1997:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.WeekStart = DayOfWeek.Sunday; r.RecurUntil = new DateTime(1997, 12, 24, 5, 0, 0).ToLocalTime(); r.ByDay.AddRange(new[] { DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other week on Tuesday and Thursday, for 8 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.WeekStart = DayOfWeek.Sunday; r.MaximumOccurrences = 8; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Thursday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the 1st Friday for ten occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 5, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 10; // There are also helper methods to add single instances r.ByDay.Add(1, DayOfWeek.Friday); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the 1st Friday until December 24, 1997:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 5, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.RecurUntil = new DateTime(1997, 12, 24, 5, 0, 0).ToLocalTime(); r.ByDay.Add(1, DayOfWeek.Friday); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other month on the 1st and last Sunday of the month for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 7, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.Interval = 2; r.MaximumOccurrences = 10; r.ByDay.AddRange(new[] { new DayInstance(1, DayOfWeek.Sunday), new DayInstance(-1, DayOfWeek.Sunday) }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the second to last Monday of the month for 6 months:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 22, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 6; r.ByDay.Add(-2, DayOfWeek.Monday); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the third to the last day of the month, forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 28, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.ByMonthDay.Add(-3); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1998, 2, 28), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1998, 2, 28, 5, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the 2nd and 15th of the month for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 10; r.ByMonthDay.AddRange(new[] { 2, 15 }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monthly on the first and last day of the month for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 30, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 10; r.ByMonthDay.AddRange(new[] { 1, -1 }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 18 months on the 10th through 15th of the month for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 10, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.Interval = 18; r.MaximumOccurrences = 10; r.ByMonthDay.AddRange(new[] { 10, 11, 12, 13, 14, 15 }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Tuesday, every other month:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.Interval = 2; r.ByDay.Add(DayOfWeek.Tuesday); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1998, 4, 1), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1998, 4, 1, 5, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Yearly in June and July for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 6, 10, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.MaximumOccurrences = 10; r.ByMonth.AddRange(new[] { 6, 7 }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every other year in January, February, and March for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 3, 10, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.Interval = 2; r.MaximumOccurrences = 10; r.ByMonth.AddRange(new[] { 1, 2, 3 }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 3rd year on the 1st, 100th and 200th day for 10 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 1, 1, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.Interval = 3; r.MaximumOccurrences = 10; r.ByYearDay.AddRange(new[] { 1, 100, 200 }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 20th Monday of the year, forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 5, 19, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByDay.Add(20, DayOfWeek.Monday); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(2004, 5, 19), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(2004, 5, 19, 4, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Monday of week number 20 (where the default start of the week is Monday), forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 5, 12, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByWeekNo.Add(20); r.ByDay.Add(DayOfWeek.Monday); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(2004, 5, 19), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(2004, 5, 19, 4, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Thursday in March, forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 3, 13, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByMonth.Add(3); r.ByDay.Add(DayOfWeek.Thursday); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1999, 4, 1), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1999, 4, 1, 5, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Thursday, but only during June, July, and August, forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 6, 5, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.ByMonth.AddRange(new[] { 6, 7, 8 }); r.ByDay.Add(DayOfWeek.Thursday); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1999, 9, 1), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1999, 9, 1, 4, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every Friday the 13th, forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.ByDay.Add(DayOfWeek.Friday); r.ByMonthDay.Add(13); // This one uses an EXDATE property to remove the starting date ExDateProperty exdate = vevent.ExceptionDates.Add(startDateTime.TimeZoneDateTime); exdate.TimeZoneId = startDateTime.TimeZoneId; // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(2003, 12, 31), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(2003, 12, 31, 5, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(exdate.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); // Clear the exception date vevent.ExceptionDates.Clear(); //----------------------------------------------------------------- Console.WriteLine("The first Saturday that follows the first Sunday of the month, forever:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 13, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.ByDay.Add(DayOfWeek.Saturday); r.ByMonthDay.AddRange(new[] { 7, 8, 9, 10, 11, 12, 13 }); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1998, 7, 1), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1998, 7, 1, 4, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every four years, the first Tuesday after a Monday in November, forever (U.S. " + "Presidential Election day):"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1996, 11, 5, 9, 0, 0); r.Frequency = RecurFrequency.Yearly; r.Interval = 4; r.ByMonth.Add(11); r.ByDay.Add(DayOfWeek.Tuesday); r.ByMonthDay.AddRange(new[] { 2, 3, 4, 5, 6, 7, 8 }); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(2004, 11, 3), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(2004, 11, 3, 5, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("The 3rd instance into the month of one of Tuesday, Wednesday or Thursday, for " + "the next 3 months:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 4, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.MaximumOccurrences = 3; r.BySetPos.Add(3); r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("The 2nd to last weekday of the month:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 29, 9, 0, 0); r.Frequency = RecurFrequency.Monthly; r.BySetPos.Add(-2); r.ByDay.AddRange(new[] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday }); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1998, 9, 29), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1998, 9, 29, 4, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 3 hours from 9:00 AM to 5:00 PM on a specific day:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Hourly; r.Interval = 3; r.RecurUntil = new DateTime(1997, 9, 2, 21, 0, 0).ToLocalTime(); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 15 minutes for 6 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Minutely; r.Interval = 15; r.MaximumOccurrences = 6; dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every hour and a half for 4 occurrences:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Minutely; r.Interval = 90; r.MaximumOccurrences = 4; dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Every 20 minutes from 9:00 AM to 4:40 PM every day:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Daily; r.ByHour.AddRange(new[] { 9, 10, 11, 12, 13, 14, 15, 16 }); r.ByMinute.AddRange( new[] { 0, 20, 40 }); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1997, 9, 4), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1997, 9, 4, 4, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- // Like the last one but with a MINUTELY frequency Console.WriteLine("Every 20 minutes from 9:00 AM to 4:40 PM every day:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 9, 2, 9, 0, 0); r.Frequency = RecurFrequency.Minutely; r.Interval = 20; r.ByHour.AddRange(new[] { 9, 10, 11, 12, 13, 14, 15, 16 }); // Not forever for the test dtiTZ = vevent.InstancesBetween(startDateTime.TimeZoneDateTime, new DateTime(1997, 9, 4), false); dtiLocal = vevent.InstancesBetween(startDateTime.DateTimeValue, new DateTime(1997, 9, 4, 4, 0, 0).ToLocalTime(), true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("... Forever ...\nPress ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("An example where the days generated makes a difference because of WKST:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 8, 5, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.MaximumOccurrences = 4; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Sunday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); //----------------------------------------------------------------- Console.WriteLine("Changing only WKST from the default MO to SU yields different results:"); r.Reset(); startDateTime.TimeZoneDateTime = new DateTime(1997, 8, 5, 9, 0, 0); r.Frequency = RecurFrequency.Weekly; r.Interval = 2; r.MaximumOccurrences = 4; r.WeekStart = DayOfWeek.Sunday; r.ByDay.AddRange(new[] { DayOfWeek.Tuesday, DayOfWeek.Sunday }); dtiTZ = vevent.AllInstances(false); dtiLocal = vevent.AllInstances(true); Console.Write(startDateTime.ToString()); Console.Write(rrule.ToString()); for(idx = 0; idx < dtiTZ.Count; idx++) Console.WriteLine("TZ: {0:G} {1} Local: {2:G} {3}", dtiTZ[idx].StartDateTime, dtiTZ[idx].AbbreviatedStartTimeZoneName, dtiLocal[idx].StartDateTime, dtiLocal[idx].AbbreviatedStartTimeZoneName); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); }
/// <summary> /// This is used to filter the secondly frequency 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> public int BySecond(Recurrence r, RecurDateTimeCollection dates) { int count = dates.Count; // Don't bother if either collection is empty if(count != 0 && r.BySecond.Count != 0) for(int idx = 0, nCollIdx = 0; idx < count; idx++) { // Remove the date/time if the second isn't wanted if(!r.isSecondUsed[dates[nCollIdx].Second]) { dates.RemoveAt(nCollIdx); count--; idx--; } else nCollIdx++; } return dates.Count; }
static void Main(string[] args) { DateTime testDate, nextDate; HashSet<DateTime> holidayDates; DateTimeCollection recurDates; int yearFrom, yearTo, idx; if(args.GetUpperBound(0) < 1) { Console.WriteLine("Specify a starting and ending year"); return; } try { yearFrom = Convert.ToInt32(args[0]); yearTo = Convert.ToInt32(args[1]); if(yearFrom < 1) yearFrom = 1; if(yearFrom > 9999) yearFrom = 9999; if(yearTo < 1) yearTo = 1; if(yearTo > 9999) yearTo = 9999; if(yearFrom > yearTo) { idx = yearFrom; yearFrom = yearTo; yearTo = idx; } } catch { Console.WriteLine("Invalid year specified on command line"); return; } // Test DateUtils.CalculateOccurrenceDate Console.WriteLine("Fourth weekday in January 2004: {0:d}", DateUtils.CalculateOccurrenceDate(2004, 1, DayOccurrence.Fourth, DaysOfWeek.Weekdays, 0)); Console.WriteLine("Fourth weekday in January 2004 + 2: {0:d}", DateUtils.CalculateOccurrenceDate(2004, 1, DayOccurrence.Fourth, DaysOfWeek.Weekdays, 2)); Console.WriteLine("Last weekend day in January 2004: {0:d}", DateUtils.CalculateOccurrenceDate(2004, 1, DayOccurrence.Last, DaysOfWeek.Weekends, 0)); Console.WriteLine("Last weekend day in January 2004 + 2: {0:d}", DateUtils.CalculateOccurrenceDate(2004, 1, DayOccurrence.Last, DaysOfWeek.Weekends, 2)); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test DateUtils.DateFromWeek(), DateUtils.WeeksInYear(), and DateUtils.WeekFromDate() DateTime weekFrom, weekTo; int year; Console.WriteLine("Week start = Monday"); DayOfWeek dow = DayOfWeek.Monday; for(year = 1998; year < 2010; year++) { for(idx = 1; idx < 54; idx++) if(idx != 53 || DateUtils.WeeksInYear(year, dow) == 53) { weekFrom = DateUtils.DateFromWeek(year, idx, dow, 0); weekTo = DateUtils.DateFromWeek(year, idx, dow, 6); Console.WriteLine("{0} Week {1}: {2:d} - {3:d} {4}", year, idx, weekFrom, weekTo, DateUtils.WeekFromDate(weekFrom.AddDays(3), dow)); } // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); } // Test DateUtils.EasterSunday() Console.WriteLine("Easter - Gregorian"); for(idx = yearFrom; idx <= yearTo; idx += 3) { testDate = DateUtils.EasterSunday(idx, EasterMethod.Gregorian); Console.Write("{0} {1}/{2:00} ", idx, testDate.Month, testDate.Day); testDate = DateUtils.EasterSunday(idx + 1, EasterMethod.Gregorian); Console.Write("{0} {1}/{2:00} ", idx + 1, testDate.Month, testDate.Day); testDate = DateUtils.EasterSunday(idx + 2, EasterMethod.Gregorian); Console.WriteLine("{0} {1}/{2:00}", idx + 2, testDate.Month, testDate.Day); } Console.WriteLine("\nEaster - Julian"); for(idx = yearFrom; idx <= yearTo; idx += 3) { testDate = DateUtils.EasterSunday(idx, EasterMethod.Julian); Console.Write("{0} {1}/{2:00} ", idx, testDate.Month, testDate.Day); testDate = DateUtils.EasterSunday(idx + 1, EasterMethod.Julian); Console.Write("{0} {1}/{2:00} ", idx + 1, testDate.Month, testDate.Day); testDate = DateUtils.EasterSunday(idx + 2, EasterMethod.Julian); Console.WriteLine("{0} {1}/{2:00}", idx + 2, testDate.Month, testDate.Day); } Console.WriteLine("\nEaster - Orthodox"); for(idx = yearFrom; idx <= yearTo; idx += 3) { testDate = DateUtils.EasterSunday(idx, EasterMethod.Orthodox); Console.Write("{0} {1}/{2:00} ", idx, testDate.Month, testDate.Day); testDate = DateUtils.EasterSunday(idx + 1, EasterMethod.Orthodox); Console.Write("{0} {1}/{2:00} ", idx + 1, testDate.Month, testDate.Day); testDate = DateUtils.EasterSunday(idx + 2, EasterMethod.Orthodox); Console.WriteLine("{0} {1}/{2:00}", idx + 2, testDate.Month, testDate.Day); } // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test DateUtils.FromISO8601String and DateUtils.FromISO8601TimeZone Console.WriteLine("Expressed in Universal Time"); Console.WriteLine("20040314 = {0}", DateUtils.FromISO8601String("20040314", false)); Console.WriteLine("20040314T10 = {0}", DateUtils.FromISO8601String("20040314T10", false)); Console.WriteLine("20040314T1025 = {0}", DateUtils.FromISO8601String("20040314T1025", false)); Console.WriteLine("20040314T102531 = {0}", DateUtils.FromISO8601String("20040314T102531", false)); Console.WriteLine("20040314T102531.123 = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("20040314T102531.123", false)); Console.WriteLine("20040314T102531.98Z = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("20040314T102531.98Z", false)); Console.WriteLine("20040314T102531-04 = {0}", DateUtils.FromISO8601String("20040314T102531-04", false)); Console.WriteLine("20040314T102531.123+0830 = {0}", DateUtils.FromISO8601String("20040314T102531.123+0830", false)); Console.WriteLine("\n2004-03-14 = {0}", DateUtils.FromISO8601String("2004-03-14", false)); Console.WriteLine("2004-03-14T10 = {0}", DateUtils.FromISO8601String("2004-03-14T10", false)); Console.WriteLine("2004-03-14T10:25 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25", false)); Console.WriteLine("2004-03-14T10:25:31 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25:31", false)); Console.WriteLine("2004-03-14T10:25:31.123 = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("2004-03-14T10:25:31.123", false)); Console.WriteLine("2004-03-14T10:25:31.98Z = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("2004-03-14T10:25:31.98Z", false)); Console.WriteLine("2004-03-14T10:25:31-04 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25:31-04", false)); Console.WriteLine("2004-03-14T10:25:31+08:30 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25:31+08:30", false)); // Test DateUtils.FromISO8601String and DateUtils.FromISO8601TimeZone Console.WriteLine("\nExpressed in Local Time"); Console.WriteLine("20040314 = {0}", DateUtils.FromISO8601String("20040314", true)); Console.WriteLine("20040314T10 = {0}", DateUtils.FromISO8601String("20040314T10", true)); Console.WriteLine("20040314T1025 = {0}", DateUtils.FromISO8601String("20040314T1025", true)); Console.WriteLine("20040314T102531 = {0}", DateUtils.FromISO8601String("20040314T102531", true)); Console.WriteLine("20040314T102531.123 = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("20040314T102531.123", true)); Console.WriteLine("20040314T102531.98Z = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("20040314T102531.98Z", true)); Console.WriteLine("20040314T102531-04 = {0}", DateUtils.FromISO8601String("20040314T102531-04", true)); Console.WriteLine("20040314T102531.123+0830 = {0}", DateUtils.FromISO8601String("20040314T102531.123+0830", true)); Console.WriteLine("\n2004-03-14 = {0}", DateUtils.FromISO8601String("2004-03-14", true)); Console.WriteLine("2004-03-14T10 = {0}", DateUtils.FromISO8601String("2004-03-14T10", true)); Console.WriteLine("2004-03-14T10:25 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25", true)); Console.WriteLine("2004-03-14T10:25:31 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25:31", true)); Console.WriteLine("2004-03-14T10:25:31.123 = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("2004-03-14T10:25:31.123", true)); Console.WriteLine("2004-03-14T10:25:31.98Z = {0:d} {0:HH:mm:ss.fff}", DateUtils.FromISO8601String("2004-03-14T10:25:31.98Z", true)); Console.WriteLine("2004-03-14T10:25:31-04 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25:31-04", true)); Console.WriteLine("2004-03-14T10:25:31+08:30 = {0}", DateUtils.FromISO8601String("2004-03-14T10:25:31+08:30", true)); TimeSpan ts = DateUtils.FromISO8601TimeZone("+08"); Console.WriteLine("\n+08 = {0} hours {1} minutes", ts.Hours, ts.Minutes); ts = DateUtils.FromISO8601TimeZone("-08"); Console.WriteLine("-08 = {0} hours {1} minutes", ts.Hours, ts.Minutes); ts = DateUtils.FromISO8601TimeZone("-0830"); Console.WriteLine("-0830 = {0} hours {1} minutes", ts.Hours, ts.Minutes); ts = DateUtils.FromISO8601TimeZone("+08:30"); Console.WriteLine("+08:30 = {0} hours {1} minutes", ts.Hours, ts.Minutes); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test the Duration class Console.WriteLine("Assumptions: 1 year = {0} days, 1 month = {1} days\n", Duration.DaysInOneYear, Duration.DaysInOneMonth); Duration d = new Duration("P1Y2M3W4DT5H6M7S"); Console.WriteLine("P1Y2M3W4DT5H6M7S = {0}", d.ToString()); Console.WriteLine("P1Y2M3W4DT5H6M7S = {0} (max units = months)", d.ToString(Duration.MaxUnit.Months)); d = new Duration("P10Y11MT16M12S"); Console.WriteLine("P10Y11MT16M12S = {0}", d.ToString()); d = new Duration("P5M2DT16M"); Console.WriteLine("P5M2DT16M = {0}", d.ToString()); d = new Duration("P7W"); Console.WriteLine("P7W = {0}", d.ToString()); Console.WriteLine("P7W = {0} (max units = weeks)", d.ToString(Duration.MaxUnit.Weeks)); Console.WriteLine("P7W = {0} (max units = days)", d.ToString(Duration.MaxUnit.Days)); d = new Duration("P7W2D"); Console.WriteLine("P7W2D = {0}", d.ToString()); Console.WriteLine("P7W2D = {0} (max units = weeks)", d.ToString(Duration.MaxUnit.Weeks)); Console.WriteLine("P7W2D = {0} (max units = days)", d.ToString(Duration.MaxUnit.Days)); d = new Duration("P5DT2S"); Console.WriteLine("P5DT2S = {0}", d.ToString()); d = new Duration("PT24H"); Console.WriteLine("PT24H = {0}", d.ToString()); Console.WriteLine("PT24H = {0} (max units = hours)", d.ToString(Duration.MaxUnit.Hours)); Console.WriteLine("PT24H = {0} (max units = minutes)", d.ToString(Duration.MaxUnit.Minutes)); Console.WriteLine("PT24H = {0} (max units = seconds)", d.ToString(Duration.MaxUnit.Seconds)); d = new Duration("PT24H3M2S"); Console.WriteLine("PT24H3M2S = {0}", d.ToString()); Console.WriteLine("PT24H3M2S = {0} (max units = hours)", d.ToString(Duration.MaxUnit.Hours)); Console.WriteLine("PT24H3M2S = {0} (max units = minutes)", d.ToString(Duration.MaxUnit.Minutes)); Console.WriteLine("PT24H3M2S = {0} (max units = seconds)", d.ToString(Duration.MaxUnit.Seconds)); d = new Duration("PT1H10M20S"); Console.WriteLine("PT1H10M20S = {0}", d.ToString()); d = new Duration("PT5M20S"); Console.WriteLine("PT5M20S = {0}", d.ToString()); d = new Duration("PT5S"); Console.WriteLine("PT5S = {0}", d.ToString()); d = new Duration("P0Y0M0W0DT0H0M0S"); Console.WriteLine("P0Y0M0W0DT0H0M0S = {0}", d.ToString()); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); d = new Duration("-P1Y2M3W4DT5H6M7S"); Console.WriteLine("\n-P1Y2M3W4DT5H6M7S = {0}", d.ToString()); Console.WriteLine("-P1Y2M3W4DT5H6M7S = {0} (max units = months)", d.ToString(Duration.MaxUnit.Months)); d = new Duration("-P10Y11MT16M12S"); Console.WriteLine("-P10Y11MT16M12S = {0}", d.ToString()); d = new Duration("-P5M2DT16M"); Console.WriteLine("-P5M2DT16M = {0}", d.ToString()); d = new Duration("-P7W"); Console.WriteLine("-P7W = {0}", d.ToString()); Console.WriteLine("-P7W = {0} (max units = weeks)", d.ToString(Duration.MaxUnit.Weeks)); Console.WriteLine("-P7W = {0} (max units = days)", d.ToString(Duration.MaxUnit.Days)); d = new Duration("-P7W2D"); Console.WriteLine("-P7W2D = {0}", d.ToString()); Console.WriteLine("-P7W2D = {0} (max units = weeks)", d.ToString(Duration.MaxUnit.Weeks)); Console.WriteLine("-P7W2D = {0} (max units = days)", d.ToString(Duration.MaxUnit.Days)); d = new Duration("-P5DT2S"); Console.WriteLine("-P5DT2S = {0}", d.ToString()); d = new Duration("-PT24H"); Console.WriteLine("-PT24H = {0}", d.ToString()); Console.WriteLine("-PT24H = {0} (max units = hours)", d.ToString(Duration.MaxUnit.Hours)); Console.WriteLine("-PT24H = {0} (max units = minutes)", d.ToString(Duration.MaxUnit.Minutes)); Console.WriteLine("-PT24H = {0} (max units = seconds)", d.ToString(Duration.MaxUnit.Seconds)); d = new Duration("-PT24H3M2S"); Console.WriteLine("-PT24H3M2S = {0}", d.ToString()); Console.WriteLine("-PT24H3M2S = {0} (max units = hours)", d.ToString(Duration.MaxUnit.Hours)); Console.WriteLine("-PT24H3M2S = {0} (max units = minutes)", d.ToString(Duration.MaxUnit.Minutes)); Console.WriteLine("-PT24H3M2S = {0} (max units = seconds)", d.ToString(Duration.MaxUnit.Seconds)); d = new Duration("-PT1H10M20S"); Console.WriteLine("-PT1H10M20S = {0}", d.ToString()); d = new Duration("-PT5M20S"); Console.WriteLine("-PT5M20S = {0}", d.ToString()); d = new Duration("-PT5S"); Console.WriteLine("-PT5S = {0}", d.ToString()); d = new Duration("-P0Y0M0W0DT0H0M0S"); Console.WriteLine("-P0Y0M0W0DT0H0M0S = {0}", d.ToString()); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test the ToDescription() methods d = new Duration("P1Y2M3W4DT5H6M7S"); Console.WriteLine("P1Y2M3W4DT5H6M7S = {0}", d.ToDescription()); Console.WriteLine("P1Y2M3W4DT5H6M7S = {0} (max units = months)", d.ToDescription(Duration.MaxUnit.Months)); d = new Duration("P10Y11MT16M12S"); Console.WriteLine("P10Y11MT16M12S = {0}", d.ToDescription()); d = new Duration("P5M2DT16M"); Console.WriteLine("P5M2DT16M = {0}", d.ToDescription()); d = new Duration("P7W"); Console.WriteLine("P7W = {0}", d.ToDescription()); Console.WriteLine("P7W = {0} (max units = weeks)", d.ToDescription(Duration.MaxUnit.Weeks)); Console.WriteLine("P7W = {0} (max units = days)", d.ToDescription(Duration.MaxUnit.Days)); d = new Duration("P7W2D"); Console.WriteLine("P7W2D = {0}", d.ToDescription()); Console.WriteLine("P7W2D = {0} (max units = weeks)", d.ToDescription(Duration.MaxUnit.Weeks)); Console.WriteLine("P7W2D = {0} (max units = days)", d.ToDescription(Duration.MaxUnit.Days)); d = new Duration("P5DT2S"); Console.WriteLine("P5DT2S = {0}", d.ToDescription()); d = new Duration("PT24H"); Console.WriteLine("PT24H = {0}", d.ToDescription()); Console.WriteLine("PT24H = {0} (max units = hours)", d.ToDescription(Duration.MaxUnit.Hours)); Console.WriteLine("PT24H = {0} (max units = minutes)", d.ToDescription(Duration.MaxUnit.Minutes)); Console.WriteLine("PT24H = {0} (max units = seconds)", d.ToDescription(Duration.MaxUnit.Seconds)); d = new Duration("PT24H3M2S"); Console.WriteLine("PT24H3M2S = {0}", d.ToDescription()); Console.WriteLine("PT24H3M2S = {0} (max units = hours)", d.ToDescription(Duration.MaxUnit.Hours)); Console.WriteLine("PT24H3M2S = {0} (max units = minutes)", d.ToDescription(Duration.MaxUnit.Minutes)); Console.WriteLine("PT24H3M2S = {0} (max units = seconds)", d.ToDescription(Duration.MaxUnit.Seconds)); d = new Duration("PT1H10M20S"); Console.WriteLine("PT1H10M20S = {0}", d.ToDescription()); d = new Duration("PT5M20S"); Console.WriteLine("PT5M20S = {0}", d.ToDescription()); d = new Duration("PT5S"); Console.WriteLine("PT5S = {0}", d.ToDescription()); d = new Duration("P0Y0M0W0DT0H0M0S"); Console.WriteLine("P0Y0M0W0DT0H0M0S = {0}", d.ToDescription()); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); d = new Duration("-P1Y2M3W4DT5H6M7S"); Console.WriteLine("\n-P1Y2M3W4DT5H6M7S = {0}", d.ToDescription()); Console.WriteLine("-P1Y2M3W4DT5H6M7S = {0} (max units = months)", d.ToDescription(Duration.MaxUnit.Months)); d = new Duration("-P10Y11MT16M12S"); Console.WriteLine("-P10Y11MT16M12S = {0}", d.ToDescription()); d = new Duration("-P5M2DT16M"); Console.WriteLine("-P5M2DT16M = {0}", d.ToDescription()); d = new Duration("-P7W"); Console.WriteLine("-P7W = {0}", d.ToDescription()); Console.WriteLine("-P7W = {0} (max units = weeks)", d.ToDescription(Duration.MaxUnit.Weeks)); Console.WriteLine("-P7W = {0} (max units = days)", d.ToDescription(Duration.MaxUnit.Days)); d = new Duration("-P7W2D"); Console.WriteLine("-P7W2D = {0}", d.ToDescription()); Console.WriteLine("-P7W2D = {0} (max units = weeks)", d.ToDescription(Duration.MaxUnit.Weeks)); Console.WriteLine("-P7W2D = {0} (max units = days)", d.ToDescription(Duration.MaxUnit.Days)); d = new Duration("-P5DT2S"); Console.WriteLine("-P5DT2S = {0}", d.ToDescription()); d = new Duration("-PT24H"); Console.WriteLine("-PT24H = {0}", d.ToDescription()); Console.WriteLine("-PT24H = {0} (max units = hours)", d.ToDescription(Duration.MaxUnit.Hours)); Console.WriteLine("-PT24H = {0} (max units = minutes)", d.ToDescription(Duration.MaxUnit.Minutes)); Console.WriteLine("-PT24H = {0} (max units = seconds)", d.ToDescription(Duration.MaxUnit.Seconds)); d = new Duration("-PT24H3M2S"); Console.WriteLine("-PT24H3M2S = {0}", d.ToDescription()); Console.WriteLine("-PT24H3M2S = {0} (max units = hours)", d.ToDescription(Duration.MaxUnit.Hours)); Console.WriteLine("-PT24H3M2S = {0} (max units = minutes)", d.ToDescription(Duration.MaxUnit.Minutes)); Console.WriteLine("-PT24H3M2S = {0} (max units = seconds)", d.ToDescription(Duration.MaxUnit.Seconds)); d = new Duration("-PT1H10M20S"); Console.WriteLine("-PT1H10M20S = {0}", d.ToDescription()); d = new Duration("-PT5M20S"); Console.WriteLine("-PT5M20S = {0}", d.ToDescription()); d = new Duration("-PT5S"); Console.WriteLine("-PT5S = {0}", d.ToDescription()); d = new Duration("-P0Y0M0W0DT0H0M0S"); Console.WriteLine("-P0Y0M0W0DT0H0M0S = {0}", d.ToDescription()); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Create a set of fixed and floating holidays HolidayCollection holidays = new HolidayCollection(); holidays.AddFixed(1, 1, true, "New Year's Day"); holidays.AddFloating(DayOccurrence.Third, DayOfWeek.Monday, 1, 0, "Martin Luther King Day"); holidays.AddFloating(DayOccurrence.Third, DayOfWeek.Monday, 2, 0, "President's Day"); holidays.AddFloating(DayOccurrence.Last, DayOfWeek.Monday, 5, 0, "Memorial Day"); holidays.AddFixed(7, 4, true, "Independence Day"); holidays.AddFloating(DayOccurrence.First, DayOfWeek.Monday, 9, 0, "Labor Day"); holidays.AddFixed(11, 11, true, "Veteran's Day"); holidays.AddFloating(DayOccurrence.Fourth, DayOfWeek.Thursday, 11, 0, "Thanksgiving Day"); holidays.AddFloating(DayOccurrence.Fourth, DayOfWeek.Thursday, 11, 1, "Day After Thanksgiving"); holidays.AddFixed(12, 25, true, "Christmas Day"); // Serialize the holidays to a file try { // XML using(var fs = new FileStream("Holidays.xml", FileMode.Create)) { XmlSerializer xs = new XmlSerializer(typeof(HolidayCollection)); xs.Serialize(fs, holidays); Console.WriteLine("Holidays saved to Holidays.xml"); } // SOAP using(var fs = new FileStream("Holidays.soap", FileMode.Create)) { SoapFormatter sf = new SoapFormatter(); // SOAP doesn't support generics directly so use an array sf.Serialize(fs, holidays.ToArray()); Console.WriteLine("Holidays saved to Holidays.soap"); } // Binary using(var fs = new FileStream("Holidays.bin", FileMode.Create)) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, holidays); Console.WriteLine("Holidays saved to Holidays.bin\n"); } } catch(Exception ex) { Console.WriteLine("Unable to save holidays:\n{0}", ex.Message); if(ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); if(ex.InnerException.InnerException != null) Console.WriteLine(ex.InnerException.InnerException.Message); } } // Delete the collection and read it back in holidays = null; try { // XML using(var fs = new FileStream("Holidays.xml", FileMode.Open)) { XmlSerializer xs = new XmlSerializer(typeof(HolidayCollection)); holidays = (HolidayCollection)xs.Deserialize(fs); Console.WriteLine("Holidays retrieved from Holidays.xml"); } // SOAP using(var fs = new FileStream("Holidays.soap", FileMode.Open)) { SoapFormatter sf = new SoapFormatter(); // As noted, SOAP doesn't support generics to an array is used instead holidays = new HolidayCollection((Holiday[])sf.Deserialize(fs)); Console.WriteLine("Holidays retrieved from Holidays.soap"); } // Binary using(var fs = new FileStream("Holidays.bin", FileMode.Open)) { BinaryFormatter bf = new BinaryFormatter(); holidays = (HolidayCollection)bf.Deserialize(fs); Console.WriteLine("Holidays retrieved from Holidays.bin\n"); } } catch(Exception ex) { Console.WriteLine("Unable to load holidays:\n{0}", ex.Message); if(ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); if(ex.InnerException.InnerException != null) Console.WriteLine(ex.InnerException.InnerException.Message); } } // Display the holidays added to the list Console.WriteLine("Holidays on file. Is Holiday should be true for all."); foreach(Holiday hol in holidays) Console.WriteLine("Holiday Date: {0:d} Is Holiday: {1} Description: {2}", hol.ToDateTime(yearFrom), holidays.IsHoliday(hol.ToDateTime(yearFrom)), hol.Description); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Display holidays found in each year specified using the IsHoliday method Console.WriteLine("Looking for holidays using the IsHoliday method"); testDate = new DateTime(yearFrom, 1, 1); while(testDate.Year <= yearTo) { if(holidays.IsHoliday(testDate)) Console.WriteLine("Found holiday: {0:d} {1}", testDate, holidays.HolidayDescription(testDate)); testDate = testDate.AddDays(1); // Stop after each year to review output if(testDate.Month == 1 && testDate.Day == 1) { Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); } } // One more time, but use a hash set using the dates returned by the HolidaysBetween() method. For // bulk comparisons, this is faster than the above procedure using the IsHoliday method. Console.WriteLine("Looking for holidays using HolidaysBetween"); holidayDates = new HashSet<DateTime>(holidays.HolidaysBetween(yearFrom, yearTo)); if(holidayDates.Count != 0) { testDate = new DateTime(yearFrom, 1, 1); while(testDate.Year <= yearTo) { if(holidayDates.Contains(testDate)) Console.WriteLine("Found holiday: {0:d} {1}", testDate, holidays.HolidayDescription(testDate)); testDate = testDate.AddDays(1); // Stop after each year to review output if(testDate.Month == 1 && testDate.Day == 1) { Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); } } } //================================================================= // Test recurrence Recurrence rRecur = new Recurrence(); Recurrence.Holidays.AddRange(holidays); // Disallow occurrences on any of the defined holidays rRecur.CanOccurOnHoliday = false; testDate = new DateTime(yearFrom, 1, 1); // Test daily recurrence rRecur.StartDateTime = testDate; rRecur.RecurUntil = testDate.AddMonths(1); // For the enumerator rRecur.RecurDaily(2); // Serialize the recurrence to a file try { // XML using(var fs = new FileStream("Recurrence.xml", FileMode.Create)) { XmlSerializer xs = new XmlSerializer(typeof(Recurrence)); xs.Serialize(fs, rRecur); Console.WriteLine("Recurrence saved to Recurrence.xml"); } // SOAP using(var fs = new FileStream("Recurrence.soap", FileMode.Create)) { SoapFormatter sf = new SoapFormatter(); sf.Serialize(fs, rRecur); Console.WriteLine("Recurrence saved to Recurrence.soap"); } // Binary using(var fs = new FileStream("Recurrence.bin", FileMode.Create)) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, rRecur); Console.WriteLine("Recurrence saved to Recurrence.bin\n"); } } catch(Exception ex) { Console.WriteLine("Unable to save recurrence:\n{0}", ex.Message); if(ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); if(ex.InnerException.InnerException != null) Console.WriteLine(ex.InnerException.InnerException.Message); } } // Deserialize the recurrence from a file rRecur = null; try { // XML using(var fs = new FileStream("Recurrence.xml", FileMode.Open)) { XmlSerializer xs = new XmlSerializer(typeof(Recurrence)); rRecur = (Recurrence)xs.Deserialize(fs); Console.WriteLine("Recurrence restored from Recurrence.xml"); } // SOAP using(var fs = new FileStream("Recurrence.soap", FileMode.Open)) { SoapFormatter sf = new SoapFormatter(); rRecur = (Recurrence)sf.Deserialize(fs); Console.WriteLine("Recurrence retrieved from Recurrence.soap"); } // Binary using(var fs = new FileStream("Recurrence.bin", FileMode.Open)) { BinaryFormatter bf = new BinaryFormatter(); rRecur = (Recurrence)bf.Deserialize(fs); Console.WriteLine("Recurrence retrieved from Recurrence.bin\n"); } } catch(Exception ex) { Console.WriteLine("Unable to restore recurrence:\n{0}", ex.Message); if(ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); if(ex.InnerException.InnerException != null) Console.WriteLine(ex.InnerException.InnerException.Message); } } recurDates = rRecur.InstancesBetween(testDate, testDate.AddMonths(1)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Daily recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Daily recurrence on: {0:d}", dt); // Test NextInstance(). This isn't the most efficient way of searching for lots of dates but is // useful for one-off searches. nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Daily recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test weekly recurrence rRecur.StartDateTime = testDate; rRecur.RecurWeekly(1, DaysOfWeek.Monday | DaysOfWeek.Wednesday); recurDates = rRecur.InstancesBetween(testDate, testDate.AddMonths(1)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Weekly recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Weekly recurrence on: {0:d}", dt); nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Weekly recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test monthly recurrence (option 1) rRecur.StartDateTime = testDate; rRecur.RecurUntil = testDate.AddMonths(12); // For the enumerator rRecur.RecurMonthly(15, 2); recurDates = rRecur.InstancesBetween(testDate, testDate.AddMonths(12)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Monthly recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Monthly recurrence on: {0:d}", dt); nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Monthly recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test monthly recurrence (option 2) rRecur.RecurMonthly(DayOccurrence.Third, DaysOfWeek.Thursday, 3); recurDates = rRecur.InstancesBetween(testDate, testDate.AddMonths(12)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Monthly recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Monthly recurrence on: {0:d}", dt); nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Monthly recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test monthly recurrence (option 3 - a variation of option 2) rRecur.RecurMonthly(DayOccurrence.Third, DaysOfWeek.Weekends, 2); recurDates = rRecur.InstancesBetween(testDate, testDate.AddMonths(12)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Monthly recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Monthly recurrence on: {0:d}", dt); nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Monthly recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test yearly recurrence (option 1) rRecur.StartDateTime = testDate; rRecur.RecurUntil = testDate.AddYears(5); // For the enumerator rRecur.RecurYearly(5, 24, 1); recurDates = rRecur.InstancesBetween(testDate, testDate.AddYears(5)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Yearly recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Yearly recurrence on: {0:d}", dt); nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Yearly recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test yearly recurrence (option 2) rRecur.RecurYearly(DayOccurrence.Last, DaysOfWeek.Sunday, 9, 2); recurDates = rRecur.InstancesBetween(testDate, testDate.AddYears(5)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Yearly recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Yearly recurrence on: {0:d}", dt); nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Yearly recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); // Test yearly recurrence (option 3 - a variation of option 2) rRecur.RecurYearly(DayOccurrence.Last, DaysOfWeek.Weekdays, 7, 1); recurDates = rRecur.InstancesBetween(testDate, testDate.AddYears(5)); Console.WriteLine(rRecur.ToStringWithStartDateTime()); foreach(DateTime dt in recurDates) Console.WriteLine("(Collection) Yearly recurrence on: {0:d}", dt); foreach(DateTime dt in rRecur) Console.WriteLine("(Enumerator) Yearly recurrence on: {0:d}", dt); nextDate = testDate; do { nextDate = rRecur.NextInstance(nextDate, false); if(nextDate != DateTime.MinValue) { Console.WriteLine("(NextInstance) Yearly recurrence on: {0:d}", nextDate); nextDate = nextDate.AddMinutes(1); } } while(nextDate != DateTime.MinValue); // Pause to review output Console.WriteLine("Press ENTER to continue"); Console.ReadLine(); }
/// <summary> /// ByWeekNo is only applicable in the Yearly frequency and is ignored for the Daily frequency /// </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> public int ByWeekNo(Recurrence r, RecurDateTimeCollection dates) { return dates.Count; }
/// <summary> /// This is used to expand the yearly frequency 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> public int BySecond(Recurrence r, RecurDateTimeCollection dates) { return Expand.BySecond(r, dates); }
/// <summary> /// This is used to expand the yearly frequency by minute /// </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> public int ByMinute(Recurrence r, RecurDateTimeCollection dates) { return Expand.ByMinute(r, dates); }
/// <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; }
/// <summary> /// This is used to expand the yearly frequency 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> public int ByMonthDay(Recurrence r, RecurDateTimeCollection dates) { return Expand.ByMonthDay(r, dates); }
/// <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; }
/// <summary> /// This is used to filter the daily 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> public int ByYearDay(Recurrence r, RecurDateTimeCollection dates) { return Filter.ByYearDay(r, dates); }
/// <summary> /// This is used to filter 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 a date in the collection is invalid, it will be discarded</remarks> public static int ByDay(Recurrence r, RecurDateTimeCollection dates) { RecurDateTime rdt; int count = dates.Count; // Don't bother if either collection is empty if(count != 0 && r.ByDay.Count != 0) for(int idx = 0, collIdx = 0; idx < count; idx++) { rdt = dates[collIdx]; // If not valid, discard it if(!rdt.IsValidDate()) { dates.RemoveAt(collIdx); count--; idx--; continue; } // Remove the date/time if the weekday isn't wanted if(!r.isDayUsed[(int)rdt.DayOfWeek]) { dates.RemoveAt(collIdx); count--; idx--; } else collIdx++; } return dates.Count; }
/// <summary> /// This is used to filter 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 a date in the collection is invalid, it will be discarded</remarks> public static int ByMonthDay(Recurrence r, RecurDateTimeCollection dates) { RecurDateTime rdt; int count = dates.Count; // Don't bother if either collection is empty if(count != 0 && r.ByMonthDay.Count != 0) for(int idx = 0, collIdx = 0; idx < count; idx++) { rdt = dates[collIdx]; // If not valid, discard it if(!rdt.IsValidDate()) { dates.RemoveAt(collIdx); count--; idx--; continue; } // Remove the date/time if the month day isn't wanted. Check both from the start of the // month and from the end of the month. if(!r.isMonthDayUsed[rdt.Day] && !r.isNegMonthDayUsed[DateTime.DaysInMonth(rdt.Year, rdt.Month + 1) - rdt.Day + 1]) { dates.RemoveAt(collIdx); count--; idx--; } else collIdx++; } return dates.Count; }
/// <summary> /// This is used to filter the daily 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> public int ByMonth(Recurrence r, RecurDateTimeCollection dates) { return Filter.ByMonth(r, dates); }