首次出现的RRULE

时间:2018-05-07 10:26:39

标签: icalendar rrule

我目前正在尝试设置自己的假日iCalendar,我可以订阅,因为我不想依赖第三方服务。

我目前正在尝试为圣诞节制作VEVENT s。第二次,第三次和第四次出现,以及圣诞假期都是直截了当的,但是我对于第一次出现来说有很大的问题。

具体来说,问题是第一次出现可能是11月和12月(11月27日至3月12日)

如何制作定期活动(或更具体地说,RRULE)以涵盖第一次出现的所有案例?

我尝试了什么

我的第一个想法是:

FREQ=YEARLY;INTERVAL=1;BYMONTH=11,12;BYMONTHDAY=27,28,29,30,1,2,3;BYDAY=SU

这个想法是在11月27日到12月3日之间挑选一个星期天。这当然行不通,因为BYMONTH会将搜索范围扩展到11月和12月的所有日期,而BYMONTHDAY会将搜索范围限制为两个月内的搜索日期。即11月1日,11月2日,... 12月27日,12月28日,...,这当然不是我想要的。

接下来,我尝试使用BYYEARDAY=331,332,333,334,335,336,337代替BYMONTHDAYBYMONTH,但遗憾的是我的webdav服务器(Nextcloud,据我所知使用Sabre。我收到了一条错误消息"无效的BYYEARDAY规则")不支持此。

我的下一个想法是使用多个RRULE - 至少我没有看到RFC中的任何段落声明最多只允许一个RRULE。所以我最终得到了:

RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=SU;BYMONTHDAY=27,28,29,30;BYMONTH=11
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=SU;BYMONTHDAY=1,2,3;BYMONTH=12

也不行。我的最后一招是创建两个单独的VEVENT s,一个上面有第一个RRULE,另一个上面有第二个RRULE,但其他方面相同。这很有用,但让我很困惑。

有没有更好的解决方案?你会怎么做?

2 个答案:

答案 0 :(得分:1)

  

不幸的是我的webdav服务器(Nextcloud,据我所知使用Saber。我收到错误消息“Invalid BYYEARDAY rule”)不支持此功能。

嗯,我认为你应该提出一个错误报告,因为我可以告诉你的解决方案是正确的和RFC兼容的。

我尝试了使用不同库(我自己的库php-rrulerrule.js)的解决方案2和3,这两个选项似乎都运行正常。

FREQ=YEARLY;BYDAY=SU;BYYEARDAY=331,332,333,334,335,336,337

或合并2

FREQ=YEARLY;INTERVAL=1;BYDAY=SU;BYMONTHDAY=27,28,29,30;BYMONTH=11 FREQ=YEARLY;INTERVAL=1;BYDAY=SU;BYMONTHDAY=1,2,3;BYMONTH=12

将产生:

2018-12-02
2019-12-01
2020-11-29
2021-11-28
2022-11-27
2023-12-03
2024-12-01
2025-11-30
2026-11-29
2027-11-28

根据谷歌和维基百科,是未来10年第一次来临星期日的正确日期。

旁注

  

至少我没有看到RFC中的任何段落声明最多只允许一个RRULE。

虽然没有严格禁止,但在RFC 5545中,每次都提到 RRULE字面上写着:

;
; The following is OPTIONAL,
; but SHOULD NOT occur more than once.
;
rrule

Appendix A甚至在“新限制”中指出:

2.  The "RRULE" property SHOULD NOT occur more than once in a
   component.

话虽如此,多个RRULE是一个很棒的功能,我不知道他们为什么限制它。

答案 1 :(得分:0)

如果我没记错的话,第一个降临总是一年中的最后一个星期日。因此,以下规则可以解决问题:

FREQ=YEARLY;BYDAY=-5SU

查看接下来的10个结果:http://recurrence-expansion-service.appspot.com/reaas?dtstart=20181202&rrule=FREQ%3DYEARLY%3BBYDAY%3D-5SU&max_instances=10

或者换一种说法:

FREQ=YEARLY;BYDAY=SU;BYSETPOS=-5