Find last occurrence of an event in DDay.iCal

2.3k views Asked by At

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.

1

There are 1 answers

1
Arnaud Quillaud On

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.