0

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

我目前正在尝试VEVENT为圣诞节制作 s。第 2 次、第 3 次和第 4 次降临,以及圣诞节假期是直截了当的,但是我有很大的问题来模拟第一次降临。

具体来说,问题是第一次降临可以在 11 月和 12 月(11 月 27 日到 12 月 3 日)

我怎样才能制作一个重复性事件(或者,更具体地说,是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日,...,这当然不是我想要的。


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


我的下一个想法是使用多个RRULEs —— 至少我在 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在上面,但其他方面相同。这有效,但它让我感到困惑。

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

4

2 回答 2

1

不幸的是,我的 webdav 服务器(Nextcloud,据我所知使用 Sabre。我收到一条错误消息“无效的 BYYEARDAY 规则”)不支持此功能。

好吧,我认为您应该提出错误报告,因为据我所知,您的解决方案是正确的并且符合 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

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

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

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

于 2018-05-08T10:56:05.197 回答
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
于 2018-06-24T23:39:01.740 回答