0

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

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

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

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
4

2 回答 2

1

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

此外,在下一页中,它给出了一个如何评估规则的示例:

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”将应用于“1 月的每个星期日,每隔一年”。然后,“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 规则部分指定以逗号分隔的月份日期列表。

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

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

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

回答您的评论

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

于 2017-03-29T10:13:12.570 回答
0

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

RFC 5545,第 42 页说:

确定各种重复实例开始时间和日期所需的不包含在规则中的信息是从开始时间(“DTSTART”)组件属性派生的。例如,“FREQ=YEARLY;BYMONTH=1”不指定月份或时间中的特定日期。此信息将与为“DTSTART”指定的信息相同。

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

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

于 2017-05-16T10:43:34.120 回答