{"id":1509,"library":"icalendar","title":"iCalendar","description":"icalendar is an RFC 5545 compatible parser and generator of iCalendar files. It facilitates the creation, modification, and parsing of calendar data (events, todos, journals) in Python. The library is actively maintained with frequent patch releases within major versions, and new major versions are released occasionally to introduce breaking changes and new features.","status":"active","version":"7.0.3","language":"en","source_language":"en","source_url":"https://github.com/collective/icalendar","tags":["icalendar","calendar","event","parser","generator","rfc5545","datetime"],"install":[{"cmd":"pip install icalendar","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"Calendar","correct":"from icalendar import Calendar"},{"symbol":"Event","correct":"from icalendar import Event"},{"note":"Used for defining recurrence rules for events.","symbol":"vRecur","correct":"from icalendar import vRecur"},{"note":"A class for handling iCalendar datetime/date/duration types, especially for advanced parsing/serialization.","symbol":"vDDDTypes","correct":"from icalendar import vDDDTypes"}],"quickstart":{"code":"import datetime\nfrom icalendar import Calendar, Event, vRecur\n\n# --- Create an iCalendar ---\ncal = Calendar()\ncal.add('prodid', '-//My Organisation//Example Calendar App//EN')\ncal.add('version', '2.0')\n\nevent = Event()\nevent.add('summary', 'Team Standup')\n# Always use timezone-aware datetimes for iCalendar\nevent.add('dtstart', datetime.datetime(2024, 7, 10, 9, 0, 0, tzinfo=datetime.timezone.utc))\nevent.add('dtend', datetime.datetime(2024, 7, 10, 9, 15, 0, tzinfo=datetime.timezone.utc))\nevent.add('dtstamp', datetime.datetime.now(datetime.timezone.utc))\nevent['uid'] = 'event_20240710_standup@example.com'\nevent.add('location', 'Online Meeting Room')\n\n# Add a recurrence rule (e.g., daily for 5 occurrences)\nrrule = vRecur({'freq': ['DAILY'], 'count': [5]})\nevent.add('rrule', rrule)\n\ncal.add_component(event)\n\n# Serialize to iCalendar format\nical_string = cal.to_ical().decode('utf-8')\nprint(\"--- Generated iCalendar ---\")\nprint(ical_string)\n\n# --- Parse an iCalendar ---\nprint(\"\\n--- Parsed iCalendar ---\")\nparsed_cal = Calendar.from_ical(ical_string)\nfor component in parsed_cal.walk():\n    if component.name == 'VEVENT':\n        print(f\"Summary: {component.get('summary')}\")\n        print(f\"Start: {component.get('dtstart').dt}\")\n        print(f\"End: {component.get('dtend').dt}\")\n        if 'rrule' in component:\n            print(f\"Recurrence Rule: {component.get('rrule')}\")","lang":"python","description":"This quickstart demonstrates how to create an iCalendar object with an event and a recurrence rule, serialize it to an iCalendar string, and then parse that string back into a Python object to extract event details."},"warnings":[{"fix":"If you were reading from a file, explicitly read the content into a string or bytes first: `ical_data = file.read(); cal = Calendar.from_ical(ical_data)`.","message":"In v7.0.0, the `from_ical` method on `Calendar`, `Event`, and other components now expects a string (`str`) or bytes (`bytes`) object directly, instead of a file-like object.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Always use timezone-aware `datetime` objects, preferably `datetime.timezone.utc`, when adding event times to avoid ambiguity and ensure correct RFC 5545 compliance.","message":"Version 7.0.0 introduced significant changes to how datetime objects are handled, aligning more strictly with Python's standard `datetime` module. Floating datetimes (without `tzinfo`) are now treated as UTC by default if no `TZID` is specified.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Explicitly provide `tzinfo` for all `datetime` objects, e.g., using `datetime.datetime.now(datetime.timezone.utc)` or `datetime.datetime(..., tzinfo=zoneinfo.ZoneInfo('America/New_York'))` (Python >=3.9). For older Python, `pytz` is commonly used.","message":"Incorrect timezone handling is a common source of errors. If datetimes are not timezone-aware, `icalendar` might make assumptions (e.g., UTC) that don't match your intended local time.","severity":"gotcha","affected_versions":"all"},{"fix":"Update calls from `vDDDTypes(value)` to `vDDDTypes.from_str(value)` or directly use `component.add('property', value)` for common cases where `icalendar` handles the type conversion automatically.","message":"In v5.0.0, `vDDDTypes` (used for date/datetime/duration properties) is no longer directly callable. Instead, you must use its static methods `vDDDTypes.from_str()` for parsing and `vDDDTypes.to_ical()` for serialization.","severity":"breaking","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}