0

Suppose I have an iCalendar with a single event. This has a recurrence rule (RRULE) set with a COUNT to limit it, but also has some exception dates, and some exception rules.

I want to calculate the date of the last occurrence.

If the rules only had UNTILs set, this would be easy as I would know that this bounded the possible dates, so I could do the following.

IICalendar calendar = LoadCalendar();
Event evt = calendar.Events.Single();
DateTime start = evt.Start;
DateTime end = evt.RecurrenceRules.Select(r => r.Until).Max();
var lastOccurrence = evt.GetOccurrences(start, end).Last();

However, this approach will not work with a COUNT, as the exceptions can push the last occurrence indefinitely into the future (e.g. assume the first 500 dates of a weekly occurrence have been excluded - this would push the end date about 10 years into the future).

Is there a straightforward way to determine the last occurrence in this scenario? (Ultimately, I could write my own rule parser, or reflect on the one built into DDay, but I'm hoping for an easier way!).

Background

For reference, I am aiming to build a Quartz.NET Trigger which uses an iCalendar file to determine when to fire.

RB.
  • 36,301
  • 12
  • 91
  • 131

1 Answers1

1

The COUNT is associated only with the RRULE, not to the event as a whole. See rfc5545#section-3.8.5.3 :

The final recurrence set is generated by gathering all of the start DATE-TIME values generated by any of the specified "RRULE" and "RDATE" properties, and then excluding any start DATE-TIME values specified by "EXDATE" properties.

You first build a set based on the RRULE (including its COUNT value), and then you remove the ones that are mentioned in EXDATE.

In other words, if you have an RRULE with a COUNT of 500 and 100 EXDATE instances, you end up with 400 instances.

Just FYI, you mention exception rules but EXRULE has been deprecated in RFC5545.

Community
  • 1
  • 1
Arnaud Quillaud
  • 4,420
  • 1
  • 12
  • 8
  • Thanks for pointing out deprecation of EXRULE - we don't use them ourselves, but it's nice to know that I can ignore them. From your answer, it looks like I will have to write a decent chunk of code myself, which is fine - I was just hoping to find I'd missed a method in the DDay API :) – RB. Aug 14 '13 at 10:33