Rrule: Следует использовать DTSTART как первое вхождение

Созданный на 25 янв. 2015  ·  10Комментарии  ·  Источник: jakubroztocil/rrule

Согласно спецификации 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 сентября.

Самый полезный комментарий

Я согласен, по умолчанию dtstart должен быть инклюзивным, чтобы быть более совместимым с другими системами.

Я сделал код, демонстрирующий тонкости текущего поведения: https://codepen.io/arshaw/pen/qwEQNO?editors=0010

Все 10 Комментарий

Плюс 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.

screen shot 2016-03-19 at 1 41 49 pm

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 марта).

screen shot 2016-03-22 at 6 02 21 pm

Я вытащил репо и пытаюсь сузить его с помощью некоторых тестов, но любые советы приветствуются.

У меня была аналогичная проблема с 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». Над этим типом исправлений нужно немного поработать.

image

Была ли эта страница полезной?
0 / 5 - 0 рейтинги