Даты rrule смещены на неделю

Я получаю неожиданный результат, используя python-dateutilrrule модуль и мне интересно, если это WAI.

Я динамически создаю rrule с помощью:

dtstart = datetime.date(2019, 1, 7)
until = datetime.date(2029, 11, 29)
freq = MONTHLY
byweekday=MO(2)
interval = 4

Это приводит к следующему правилу

DTSTART:20190107T000000
RRULE:FREQ=MONTHLY;INTERVAL=4;UNTIL=20291129T000000;BYDAY=+2MO

Тем не менее, при генерации дат (цикл по правилу для этого модуля Python), я получаю следующие даты:

 [datetime.datetime(2019, 1, 14, 0, 0),
 datetime.datetime(2019, 5, 13, 0, 0),
 datetime.datetime(2019, 9, 9, 0, 0),
 datetime.datetime(2020, 1, 13, 0, 0),
 datetime.datetime(2020, 5, 11, 0, 0),
 datetime.datetime(2020, 9, 14, 0, 0),
 datetime.datetime(2021, 1, 11, 0, 0),
 datetime.datetime(2021, 5, 10, 0, 0),
 datetime.datetime(2021, 9, 13, 0, 0),
 datetime.datetime(2022, 1, 10, 0, 0),
 datetime.datetime(2022, 5, 9, 0, 0),
 datetime.datetime(2022, 9, 12, 0, 0),
 datetime.datetime(2023, 1, 9, 0, 0),
 datetime.datetime(2023, 5, 8, 0, 0),
 datetime.datetime(2023, 9, 11, 0, 0),
 datetime.datetime(2024, 1, 8, 0, 0),
 datetime.datetime(2024, 5, 13, 0, 0),
 datetime.datetime(2024, 9, 9, 0, 0),
 datetime.datetime(2025, 1, 13, 0, 0),
 datetime.datetime(2025, 5, 12, 0, 0),
 datetime.datetime(2025, 9, 8, 0, 0),
 datetime.datetime(2026, 1, 12, 0, 0),
 datetime.datetime(2026, 5, 11, 0, 0),
 datetime.datetime(2026, 9, 14, 0, 0),
 datetime.datetime(2027, 1, 11, 0, 0),
 datetime.datetime(2027, 5, 10, 0, 0),
 datetime.datetime(2027, 9, 13, 0, 0),
 datetime.datetime(2028, 1, 10, 0, 0),
 datetime.datetime(2028, 5, 8, 0, 0),
 datetime.datetime(2028, 9, 11, 0, 0),
 datetime.datetime(2029, 1, 8, 0, 0),
 datetime.datetime(2029, 5, 14, 0, 0),
 datetime.datetime(2029, 9, 10, 0, 0)]

Обратите внимание, что первая дата смещена на неделю! Почему это так? И это ошибка в библиотеке?

Спасибо Дэвид

2 ответа

Это не ошибка в библиотеке. 2019-01-14 это первая дата, которая соответствует вашему правилу (это второй понедельник января 2019 года). Очевидно, что python-dateutil решил не включать указанную вами дату начала, что вполне законно.

RRULE указано в RFC 5545, который гласит в разделе 3.8.5.3 (в разделе "Описание"):

Набор повторений, созданный со значением свойства DTSTART, не синхронизированным с правилом повторений, не определен.

По сути, это означает, что нет правильной или неправильной интерпретации, потому что входные данные "повреждены", если дата начала не соответствует правилу.

Обратите внимание, что многие другие реализации, вероятно, будут возвращать и вашу дату начала 2019-01-07 и результат 2019-01-14, Я не думаю, что какая-либо реализация будет опущена 2019-01-14просто потому, что это первая дата, которая соответствует правилу. Это спорный вопрос, является ли дата начала 2019-01-07 должно быть в результатах или нет, но 2019-01-14 определенно должен быть там.

В Python код by_weekly можно было бы реализовать так.

      from calendar import isleap

from datetime import datetime
from dateutil.rrule import rrule, DAILY, WEEKLY, MONTHLY 

def bi_weekly(start_date=datetime.now(),count=53,interval=2):
    """
      dateTImeSart = bi_weekly(datetime.strptime('2021-01-01', '%Y-%m-%d'),53)
      print(dateTImeSart[0].strftime("%Y-%m-%d"))
      print(dateTImeSart[1].strftime("%Y-%m-%d"))
      print(dateTImeSart[50].strftime("%Y-%m-%d"))
      print(dateTImeSart[51].strftime("%Y-%m-%d"))
      print(dateTImeSart[52].strftime("%Y-%m-%d"))
      2021-01-01
      2021-01-15
      2022-12-02
      2022-12-16
      2022-12-30
    """
    # returns the datetime for an year and calculates them for 1 By weekly
    return list(rrule(WEEKLY, count=count,interval=interval, dtstart=start_date))
Другие вопросы по тегам