Согласно спецификации iCalendar:
The "DTSTART" property defines the first instance in the recurrence set.
И это включает пример этого:
Every other week on Monday, Wednesday and Friday until December 24,
1997, but starting on Tuesday, September 2, 1997:
DTSTART;TZID=US-Eastern:19970902T090000
RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;
BYDAY=MO,WE,FR
==> (1997 9:00 AM EDT)September 2,3,5,15,17,19,29;October
1,3,13,15,17
(1997 9:00 AM EST)October 27,29,31;November 10,12,14,24,26,28;
December 8,10,12,22
rrule.js не учитывает 2 сентября как событие. В rrule.js первое появление - 3 сентября.
Плюс 1 по этому поводу. RRule вообще не соблюдает дату начала / продолжительность демонстрационного приложения.
Согласен, это сбило меня с толку при работе с Google RFC 2445 java lib.
: +1: Так работают стандартные (и совместимые системы, такие как Google Calendar, Apple (Mac OS / iOS / iCloud) Calendar.
@jkbrzt , Прямо сейчас rrule.js привязан к функционалу python dateutil
В отличие от документированного в RFC, начальная дата и время (dtstart) не является первым повторением, если оно не соответствует указанным правилам.
–– dateutil docs
Это может показаться большим отклонением от dateutil, что в данном случае имеет смысл. Это потребует изменения почти всех тестовых примеров. Мысли? Вы бы поддержали изменение?
@hwangmoretime Я объединил ваши изменения в README, где указаны отличия rrule.js от RFC, спасибо за это. Да, было бы разумно сделать rrule.js
совместимым (эта проблема + аргумент ключевого слова byday
). Однако это нарушит обратную совместимость, поэтому его необходимо хорошо задокументировать.
Я считаю, что здесь все еще есть ошибка. Это работает для all()
но не для метода between
. В приведенном ниже примере я установил dtstart
и rdate
для объекта RRuleSet
согласно readme.
rruleSet
RRuleSet {_cache: Object, _rrule: Array[1], _rdate: Array[1], _exrule: Array[0], _exdate: Array[0]}
rruleSet.valueOf ()
["RRULE:FREQ=YEARLY;DTSTART=20120122T000000Z;INTERVAL=1;WKST=0;BYMONTH=3;BYMONTHDAY=19;BYHOUR=13;BYMINUTE=39;BYSECOND=27", "RDATE:20120122T000000Z"]
rruleSet.all () [0]
Sat Jan 21 2012 16:00:00 GMT-0800 (PST)
rruleSet.between (startDatetime, endDatetime)
[Sat Mar 19 2016 13:39:27 GMT-0700 (PDT)]
обратите внимание, что для вызова метода all
возвращенная дата совпадает с исходной dtstart
но для between
умолчанию возвращается текущее время
вот еще немного контекста. Насколько я могу судить, rruleset делает прямо противоположное тому, что я ожидал. Он создает список дат, где нулевой элемент является началом исходного желаемого события. Но сейчас время расширяется до серии дат. Я ожидал получить список дат 21 января, но rruleset "повторился" с использованием текущего времени (22 марта).
Я вытащил репо и пытаюсь сузить его с помощью некоторых тестов, но любые советы приветствуются.
У меня была аналогичная проблема с dtstart. См. Https://stackoverflow.com/questions/54517101/rrule-not-setting-correct-time-if-dtstart-is-set
Когда я устанавливаю dtstart в конструкторе, я получаю правильное время с помощью .all (), но если я затем устанавливаю dtstart, я получаю текущее время.
Я согласен, по умолчанию dtstart
должен быть инклюзивным, чтобы быть более совместимым с другими системами.
Я сделал код, демонстрирующий тонкости текущего поведения: https://codepen.io/arshaw/pen/qwEQNO?editors=0010
по умолчанию
dtstart
должен быть включающим, чтобы быть более совместимым с другими системами.
Согласовано. Приступаем к рулю сейчас. Это отличная экономия времени (спасибо!), Но эта инклюзивная проблема с датой представляет собой странный нюанс, для решения которого требуется некоторая настраиваемая логика. Хотелось бы увидеть это обновленным. Понимал, что текущее поведение согласуется с python-dateutil, но я думаю, что приоритет должен быть на поведении, соответствующем стандарту RFC, а не увековечивать странное отклонение.
Кроме того, в комментарии ниже:
Обратите внимание, что вы можете получить исходное поведение, используя RRuleSet и добавив dtstart как rdate.
Насколько я могу судить, это значительно преуменьшает сложность обходного пути, необходимого для многих случаев использования.
Например, предположим, что у вас есть следующие параметры правила:
new RRule({
freq: RRule.WEEKLY,
dtstart: new Date(Date.UTC(2020, 10, 1, 21, 0, 0)),
count: 10,
interval: 2,
byweekday: RRule.MO
})
Это должно переводиться как «каждые 2 недели в понедельник 10 раз» с датой начала в воскресенье, 1 ноября 2020 года.
Итак, самый первый календарный понедельник после даты начала - 2 ноября ... поэтому с интервалом 2 мы ожидаем, что сгенерированные даты событий будут 2 ноября, 16 ноября, 30 ноября и т. Д.
Однако пакет rrule
вместо этого дает нам даты 9 ноября, 23 ноября и т. Д. Другими словами, весь наш интервал неверен, сдвинут на одну неделю вперед. Исправить это не так просто, как «использовать RRuleSet и добавить dtstart как rdate». Над этим типом исправлений нужно немного поработать.
Самый полезный комментарий
Я согласен, по умолчанию
dtstart
должен быть инклюзивным, чтобы быть более совместимым с другими системами.Я сделал код, демонстрирующий тонкости текущего поведения: https://codepen.io/arshaw/pen/qwEQNO?editors=0010