RRULE для первого пришествия

В настоящее время я пытаюсь настроить свой собственный праздничный iCalendar, на который я могу подписаться, так как я не хочу зависеть от сторонних сервисов.

В настоящее время я пытаюсь сделать VEVENTs на Рождество. 2-е, 3-е и 4-е пришествие, а также рождественские праздники прямолинейны, однако у меня большие проблемы с моделированием 1-го пришествия.

В частности, проблема в том, что первое пришествие может быть в ноябре и декабре (с 27 ноября по 3 декабря).

Как сделать повторяющееся событие (или, точнее, RRULE), чтобы охватить все случаи 1-го пришествия?

Что я пробовал


Моя первая идея была такой:

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

Идея заключалась в том, чтобы просто выбрать одно воскресенье между 27 ноября и 3 декабря. Это, конечно, не работает, потому что BYMONTH расширяет поиск на все дни ноября и декабря, а BYMONTHDAY ограничивает поиск этими днями в обоих месяцах. т.е. 1 ноября, 2 ноября, ... 27 декабря, 28 декабря, ..., что, конечно, не то, что я хочу.


Затем я попытался использовать BYYEARDAY=331,332,333,334,335,336,337 вместо BYMONTHDAY и BYMONTH, но, к сожалению, мой сервер 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, один с первым RRULE выше, а другой со вторым RRULE выше, но в остальном идентичными. Это сработало, но привело меня в замешательство.

Нет ли лучшего решения? Как бы вы это сделали?


person CharlyDelta    schedule 07.05.2018    source источник


Ответы (2)


к сожалению, мой сервер webdav (Nextcloud, который, насколько мне известно, использует Sabre. Я получил сообщение об ошибке «Недопустимое правило BYYEARDAY») не поддерживает это.

Ну, я думаю, вам следует создать отчет об ошибке, потому что, насколько я могу судить, ваши решения верны и соответствуют RFC.

Я попробовал ваши решения 2 и 3 с разными библиотеками (моя собственная библиотека php-rrule и rrule.js), и оба варианта, похоже, работают нормально.

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

которые, согласно Google и Wikipedia, являются правильными датами для 1-го Адвентистского воскресенья в следующие 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 — отличная функция, я не знаю, почему они ее ограничили.

person rlanvin    schedule 08.05.2018
comment
Спасибо, очень полезно. Я отправлю отчет об ошибке в Nextcloud, так как я не уверен, связана ли проблема с SabreDAV или какой-либо библиотекой JS (упомянутая мной ошибка была напечатана в консоли JS). Я не видел уникальности RRULE, спасибо, что указали на это. - person CharlyDelta; 08.05.2018

Если не ошибаюсь, первый Адвент всегда пятое последнее воскресенье года. Таким образом, следующее правило должно помочь:

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
person Marten    schedule 24.06.2018