假设我有一个带有单个事件的iCalendar。这有一个定期规则(RRULE),设置了COUNT
来限制它,但也有一些异常日期和一些异常规则。
我想计算最后一次发生的日期。
如果规则只设置了UNTIL
s,这将很容易,因为我知道这限制了可能的日期,所以我可以执行以下操作。
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();
然而,这种方法不适用于COUNT,因为例外情况可能会将最后一次事件无限期地推到未来(例如,假设每周事件的前500个日期已被排除在外,这将把结束日期推到大约10年后)。
有没有一种简单的方法来确定这种情况下的最后一次发生?(最终,我可以编写自己的规则分析器,或者反思DDay中内置的规则解析器,但我希望有一种更简单的方法!)。
背景
作为参考,我的目标是构建一个Quartz.NET触发器,它使用iCalendar文件来确定何时启动。
COUNT仅与RRULE关联,而不与整个事件关联。参见rfc5545#第3.5.3节:
通过收集所有的开始生成最终的重复集DATE-TIME值由任何指定的";RRULE";和"RDATE";属性,然后排除任何开始的DATE-TIME值由";EXDATE";属性。
首先基于RRULE(包括其COUNT值)构建一个集合,然后删除EXDATE中提到的集合。
换句话说,如果您有一个COUNT为500和100 EXDATE实例的RRULE,那么您最终会得到400个实例。
仅供参考,您提到了异常规则,但EXRULE在RFC5545中已被弃用。