Recurring iCal Events
This library calculates recurrence times of events, todos, alarms, and journals based on the iCalendar RFC5545 specification. It provides a convenient way to expand recurring events within a given time range from an iCalendar object. The current version is 3.8.1, with a regular release cadence as evidenced by frequent updates.
Warnings
- breaking The `end` parameter of the `between()` method (and formerly the `of()` function) is now exclusive, meaning events occurring exactly at the `end` datetime are no longer included.
- breaking The default timezone inference for events without a `TZID` parameter changed from UTC to the local system timezone.
- breaking Python 3.7 is no longer supported. The library now requires Python 3.8 or newer.
- gotcha The `of()` function's signature changed in v3.0.0, moving from `of(events, start, end)` to `of(calendar_or_events).between(start, end)`. Directly calling `of` with three arguments will raise an error.
- gotcha While `pytz` is still a dependency, the library encourages the use of Python 3.9+'s built-in `zoneinfo` module or `backports.zoneinfo` for Python 3.8 for timezone handling where possible, to align with modern Python practices.
Install
-
pip install recurring-ical-events
Imports
- recurring_ical_events
import recurring_ical_events
- of
recurring_ical_events.of(calendar).between(start_date, end_date)
Quickstart
import recurring_ical_events
import icalendar
import datetime
# An iCalendar string with a daily recurring event
calendar_string = """BEGIN:VCALENDAR\nPRODID:-//Example Corp.//iCalGen 1.0//EN\nVERSION:2.0\nBEGIN:VEVENT\nDTSTART;TZID=America/New_York:20231201T090000\nDTEND;TZID=America/New_York:20231201T100000\nRRULE:FREQ=DAILY;COUNT=3\nSUMMARY:Daily Meeting\nEND:VEVENT\nEND:VCALENDAR"""
# Parse the iCalendar string
calendar = icalendar.Calendar.from_ical(calendar_string)
# Define the period for which to get events
start_date = datetime.datetime(2023, 11, 20, tzinfo=datetime.timezone.utc)
end_date = datetime.datetime(2023, 12, 31, tzinfo=datetime.timezone.utc)
# Get recurring events within the specified period
events = recurring_ical_events.of(calendar).between(start_date, end_date)
print(f"Found {len(events)} events:")
for event in events:
print(f"- {event['SUMMARY']} on {event['DTSTART'].dt.isoformat()}")