{"id":4232,"library":"recurring-ical-events","title":"Recurring iCal Events","description":"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.","status":"active","version":"3.8.1","language":"python","source_language":"en","source_url":"https://github.com/niccokunzmann/python-recurring-ical-events","tags":["icalendar","recurrence","events","scheduling","datetime","RFC5545"],"install":[{"cmd":"pip install recurring-ical-events","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core dependency for parsing and handling iCalendar data.","package":"icalendar","optional":false},{"reason":"Used for robust date/time parsing and manipulation.","package":"python-dateutil","optional":false},{"reason":"Provides timezone definitions, though the library increasingly uses built-in `zoneinfo` for Python 3.9+.","package":"pytz","optional":false},{"reason":"Provides robust parsing of RFC5545 recurrence rules.","package":"rfc5545-parser","optional":false}],"imports":[{"symbol":"recurring_ical_events","correct":"import recurring_ical_events"},{"note":"The signature of `of` changed significantly in v3.0.0. It now returns an object with a `between` method.","wrong":"recurring_ical_events.of(events, period_start, period_end)","symbol":"of","correct":"recurring_ical_events.of(calendar).between(start_date, end_date)"}],"quickstart":{"code":"import recurring_ical_events\nimport icalendar\nimport datetime\n\n# An iCalendar string with a daily recurring event\ncalendar_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\"\"\"\n\n# Parse the iCalendar string\ncalendar = icalendar.Calendar.from_ical(calendar_string)\n\n# Define the period for which to get events\nstart_date = datetime.datetime(2023, 11, 20, tzinfo=datetime.timezone.utc)\nend_date = datetime.datetime(2023, 12, 31, tzinfo=datetime.timezone.utc)\n\n# Get recurring events within the specified period\nevents = recurring_ical_events.of(calendar).between(start_date, end_date)\n\nprint(f\"Found {len(events)} events:\")\nfor event in events:\n    print(f\"- {event['SUMMARY']} on {event['DTSTART'].dt.isoformat()}\")","lang":"python","description":"This quickstart demonstrates how to parse an iCalendar string, extract a recurring event, and then expand its occurrences within a specified date range using the `recurring_ical_events` library. It uses `icalendar` for parsing the base calendar and `datetime` for defining the period."},"warnings":[{"fix":"If you need to include events exactly on the end date, adjust your `end` datetime to be one unit (e.g., one second or one day) after your desired inclusive end.","message":"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.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Explicitly set `DTSTART` and `DTEND` with `TZID` for all events where timezone certainty is critical, or ensure your local system timezone matches expectations, especially when dealing with events lacking explicit timezone information.","message":"The default timezone inference for events without a `TZID` parameter changed from UTC to the local system timezone.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade your Python environment to 3.8 or a later version to use `recurring-ical-events` v3.0.0 and above.","message":"Python 3.7 is no longer supported. The library now requires Python 3.8 or newer.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Update your code to use the new chained method call: `recurring_ical_events.of(calendar).between(start_date, end_date)`.","message":"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.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Prefer `datetime.timezone.utc` or `zoneinfo.ZoneInfo` for defining timezone-aware datetimes when interacting with the library, especially in new code.","message":"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.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"search_vec":"'3.8.1':43 'alarm':12 'base':15 'cadenc':48 'calcul':6 'conveni':24 'current':40 'datetim':58 'event':3,10,29,56 'evidenc':50 'expand':27 'frequent':52 'given':32 'ical':2 'icalendar':18,37,54 'journal':14 'librari':5 'object':38 'provid':22 'rang':34 'recur':1,28 'recurr':7,55 'regular':46 'releas':47 'rfc5545':19,59 'schedul':57 'specif':20 'time':8,33 'todo':11 'updat':53 'version':41 'way':25 'within':30","created_at":"2026-04-12T03:46:35.315684+00:00","updated_at":"2026-04-17T14:19:39.453769+00:00","problems":[{"fix":"Install the module using pip: 'pip install recurring-ical-events'.","cause":"The 'recurring_ical_events' module is not installed in the Python environment.","error":"ModuleNotFoundError: No module named 'recurring_ical_events'"},{"fix":"Use the correct function to parse the calendar, such as 'recurring_ical_events.icalendar.Calendar'.","cause":"The 'of' function is not a valid attribute of the 'recurring_ical_events' module.","error":"AttributeError: module 'recurring_ical_events' has no attribute 'of'"},{"fix":"Ensure the iCalendar file is correctly parsed and the resulting object is not 'None' before calling 'between'.","cause":"The 'between' method is called on a 'None' object, likely due to a failed parsing of the iCalendar file.","error":"TypeError: 'NoneType' object is not iterable"},{"fix":"Verify the recurrence rule string adheres to the iCalendar RFC 5545 specification and correct any formatting errors.","cause":"The recurrence rule string is improperly formatted or contains invalid parameters.","error":"ValueError: Invalid recurrence rule: 'FREQ=DAILY;COUNT=3;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR'"},{"fix":"Check the module's documentation for the correct import statements and available functions.","cause":"Attempting to import a non-existent 'of' function from the 'recurring_ical_events' module.","error":"ImportError: cannot import name 'of' from 'recurring_ical_events'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"3.8.2","cli_name":"","cli_version":null,"type":"library","homepage":"https://recurring-ical-events.readthedocs.io/","github":"https://github.com/niccokunzmann/python-recurring-ical-events?tab=readme-ov-file#changelog","docs":"https://github.com/niccokunzmann/python-recurring-ical-events","changelog":"https://github.com/niccokunzmann/python-recurring-ical-events?tab=readme-ov-file#changelog","pypi":"https://pypi.org/project/recurring-ical-events/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-29","next_check":"2026-07-28","install_tag":null}}