【问题标题】:iCalendar YEARLY rrule without BYMONTH value没有 BYMONTH 值的 iCalendar YEARLY 规则
【发布时间】:2017-05-16 18:43:34
【问题描述】:

我正在构建一个接受 icalendar 事件并计算重复事件的所有发生的东西。

我发现了一个问题,它每个月都会给我返回几个 YEARLY 事件。 这些事件有一个年度频率,但只有 bymonthday 没有 bymonth 值。

这是在 RFC-5545 中指定的,还是只是我的日历工具中的一个错误。 (PS:这实际上是在我的 Google 日历中,并且该事件在那里正确显示)

BEGIN:VEVENT
DTSTART;VALUE=DATE:20110814
DTEND;VALUE=DATE:20110815
RRULE:FREQ=YEARLY;BYMONTHDAY=14
DTSTAMP:20170328T223152Z 
UID:388B4AE8602346DAA7BD9C1906FC390200000000000000000000000000000000
CREATED:20110610T073603Z
DESCRIPTION:
LAST-MODIFIED:20160811T230008Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Some BDAY
TRANSP:OPAQUE
CATEGORIES:http://schemas.google.com/g/2005#event
BEGIN:VALARM
ACTION:AUDIO
TRIGGER:-P1DT15H
ACKNOWLEDGED:20160811T230006Z
ATTACH;VALUE=URI:Basso
UID:26C6C0F7-8B77-4E20-8EFD-E82A614B0751
X-WR-ALARMUID:26C6C0F7-8B77-4E20-8EFD-E82A614B0751
END:VALARM
BEGIN:VALARM
ACTION:NONE
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
END:VALARM
END:VEVENT

【问题讨论】:

    标签: icalendar rrule


    【解决方案1】:

    在 RFC 5545 中 - 确切地说是 page 44 - BYMONTHDAY 被指定为扩展年度规则,即生成更多的结果,而不是每年只有 1 个。

    此外,the next page 提供了一个如何评估规则的示例:

    DTSTART;TZID=America/New_York:19970105T083000
    
      RRULE:FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;
      BYMINUTE=30
    

    首先,“INTERVAL=2”将应用于“FREQ=YEARLY”以 到达“每隔一年”。然后,将应用“BYMONTH=1” 到达“每年一月,每隔一年”。然后,“BYDAY=SU” 将适用于到达“一月的每个星期日,每个 另一年”。然后,将应用“BYHOUR=8,9”来到达 “1 月的每个星期日早上 8 点和 9 点,每隔一年”。 然后,将应用“BYMINUTE=30”来到达“每个星期日 隔年 1 月上午 8:30 和上午 9:30”。

    如您所见,即使 FREQ 为 YEARLY,该规则也会返回“1 月的每个星期日上午 8 点和 9 点,每隔一年”,即每两年发生一次以上。简而言之,就是扩展 FREQ 行为的概念。

    现在适用于这条规则:

    RRULE:FREQ=YEARLY;BYMONTHDAY=14

    意思是“每个月的 14 号,每年”。因此,您每年将出现 12 次。

    编辑:话虽如此,重新阅读RFC后,BYMONTHDAY的定义是:

    BYMONTHDAY 规则部分指定以逗号分隔的月份日期列表。

    这可以解释为“ 月的天列表”,如“仅由DTSTART 属性指定的 月”。然而,这种解释对于 FREQ 的其他值(MONTHLY、DAILY 等)没有意义,所以这只是 FREQ=YEARLY 和 BYMONTH 缺失的特殊情况......我个人认为这是不正确的,但是我必须承认 RFC 有点模棱两可。

    不幸的是,没有任何 BYMONTHDAY 的例子,FREQ=YEARLY 没有 BYMONTH,所以没有明确的答案

    结论:为避免任何问题,如果您只想要“给定月份的 14 号”,则应添加 BYMONTH

    回答您的评论

    规则“FREQ=MONTHLY;BYMONTHDAY=14”确实产生了相同的结果。 INTERVAL 大于 1 或其他 BYxxx 时会出现差异。

    【讨论】:

    • 这条规则 RRULE:FREQ=YEARLY;BYMONTHDAY=14 是否与 RRULE:FREQ=MONTHLY;BYMONTHDAY=14 不同?我已在 Google 日历中设置此事件每年 8 月 14 日发生一次,这是否意味着 Google 日历已使用错误的 RRULE 存储此事件?
    • @maxiC 我已经编辑并完成了我的答案。我不能肯定地说 Google 日历是错误的,但它肯定非常模棱两可。
    • 好的,感谢您的大力帮助!指定了 INTERVAL 的两者之间的区别肯定是有道理的。
    【解决方案2】:

    IMO FREQ=YEARLY;BYMONTHDAY=14 应该只在每年的 8 月 14 日生成一个事件。

    RFC 5545, page 42 说:

    不包含在规则中的信息,用于确定 各种重复实例开始时间和日期来自 开始时间 ("DTSTART") 组件属性。例如, "FREQ=YEARLY;BYMONTH=1" 没有在 一个月或一次。此信息将与 为“DTSTART”指定。

    因此,在您的情况下,规则没有指定月份,因此它是从开始日期继承的。在你的情况下,那是八月。

    查看我们的库为此事件生成的实例:FREQ=YEARLY;BYMONTHDAY=14

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-21
      • 2012-04-10
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      相关资源
      最近更新 更多