当BYMONTH,BYWEEKNO,BYYEARDAY不止一个人出现时,每年的RRULE解释

时间:2018-01-02 16:19:22

标签: icalendar rrule

我目前正在努力解决RFC 5545的解释细节问题。Section 3.3.10说明基本上所有BYxxx字段都显示扩展行为,但BYDAY除外,具有特定的规则,具体取决于实际存在的BYxxx个字段。

但是,我不清楚RRULE指定<BYMONTHBYWEEKNO,{{1>}多个BYYEARDAY应该发生什么? {1}}}。在我看来,第3.3.10节中的表允许我必须分别展开每个规则部分的解释,即构建由

产生的三个集合的并集。
  1. 展开BYMONTHBYMONTHDAY
  2. 展开BYWEEKNO
  3. 展开BYYEARDAY
  4. 始终遵守解释BYDAY行为的注释2。结果可能有点违反直觉(当然用户很可能不会指定这样的规则)。但至少有一个实现claims to do it this way

      

    对于YEARLY频率,BYMONTHBYWEEKNOBYYEARDAY规则会在指定时彼此分开展开。

    如果存在多个规则部分,其他实施(例如http://recurrence-expansion-service.appspot.com/或Google日历)似乎使用限制策略:

    1. 展开BYMONTH / BYMONTHDAY
    2. 然后使用BYWEEKNOBYYEARDAY
    3. 进行限制

      有效地创造一个十字路口而不是一个工会。该方法似乎与第3.3.10节规定的规则部分的应用程序顺序有些一致:

        

      如果指定了多个BYxxx规则部分,则在评估之后   指定的FREQINTERVAL规则部分,BYxxx规则部分   应用于当前评估的事件集   遵循以下顺序:BYMONTHBYWEEKNOBYYEARDAYBYMONTHDAYBYDAY,   BYHOURBYMINUTEBYSECONDBYSETPOS;然后是COUNTUNTIL   评价。

      但是,解释这意味着规则部分限制而不是扩展在我看来与{{{}上显示的扩展/限制表直接矛盾3}}

      我的问题是:

      RFC5545是否实际上明确指定了如何解释同时存在多个BYMONTHBYWEEKNOBYYEARDAY?如果是这样,它在哪里说明了什么?如果标准在这方面实际上不清楚,是否有一种“事实上的标准”处理这种情况的首选方式?

1 个答案:

答案 0 :(得分:2)

  

RFC5545是否真正明确地指定了如何同时存在多个BYMONTH,BYWEEKNO和BYYEARDAY?

是的,在您在问题中引用的摘录中:按顺序将应用于当前的评估事件

术语当前评估事件的集合是句子的关键部分。例如,让我们采用BYMONTH和BYYEARDAY规则。

  1. 首先评估BYMONTH,生成一组出现次数(,即每年不止一次出现)
  2. 只有然后 BYYEARDAY应用于仅这些事件,即与BYMONTH匹配的事件。每年都不考虑与BYMONTH不匹配的日期,因为根据定义,它不是步骤1中计算的当前事件集的一部分。
  3. 在这种情况下,扩展/限制表无关紧要。 RFC非常清楚地说明了:

      

    &#34;下表总结了BYxxx规则部分扩展或限制行为对FREQ规则部分值的依赖性。&#34;

    该表总结了BYxxx规则部分在其他BYxxx规则部分上的行为。

    因此,它是一个明确的交叉点。可以这样想:如果结果是一个联盟,就没有办法写出诸如&#34之类的规则;每年的第5周都是2月和#34; (FREQ=YEARLY;BYWEEKNO=5;BYMONTH=2)。

    为了实现 union ,RFC定义了一个重复集,它简单地组合了多个RRULE,RDATE和EXDATE(尽管由于某种原因,RFC声明RRULE < em>不应该出现多次。)

      

    如果标准在这方面实际上不清楚,是否有“事实上的标准”处理这种情况的首选方式?

    我是php-rrule的维护者,它是Python dateutil的一个端口,这就是两个版本处理这种情况的方式。据我所知,Javascript和Ruby库也以这种方式工作。我不了解其他所有库,但无论如何RFC都很清楚,我希望我已经在上面演示了。

    编辑:回答您对BYDAY的评论

    表格的注释2确实很混乱,所以这里有一点澄清。 BYDAY之所以特别,是因为它有2种语法:简单的语法具有当天的名称(例如MOTU等等)和&#34;复杂的&#34;一个具有日期名称​​和集合中的位置。例如1MO表示&#34;第一个周一&#34;和-1MO&#34;上周一&#34;。但问题是&#34; 是什么的第一个/最后一个星期一?&#34;。

    • 当使用YEARLY频率和BYDAY=1MO,2MO时,它是&#34;一年中的第一个和第二个星期一&#34;,当使用MONTHLY时,它是&#34;第一个和第二个星期一这个月&#34;等等,这非常简单。
    • 但是,当使用YEARLY频率 BYMONTH=2,3时,规则实际上意味着&#34;每年2月和3月&#34;所以问题是:你应该得到2月和3月的第一个和第二个星期一(扩展),或者2月和3月发生的每年的第一个和第二个星期一 - 即空集,因为两者都是是在1月(限制)。答案是做一个特殊的扩展&#34;通过实际将其视为&#34;每月&#34;频率(即使是年度),因此BYDAY=1MO,2MO的含义会在2月的第一个和第二个星期一以及3月的每个第一个和第二个星期一变为&#34。

    引用RFC的相关部分

      

    a中的数值        BYDAY规则部分与FREQ规则部分设置为YEARLY对应        到BYMONTH规则部分的月份内的偏移量        当前,并且对应于年内的偏移量        BYWEEKNO或BYMONTH规则部分存在。

    说实话,我不确定为什么BYDAY会有这种特殊情况,但无论如何它都应该很清楚它应该如何表现。