Creating iCalendar files in Python
Posted: | Tags: datetime tilSchedules, events and alarms can be shared using the iCalendar data format regardless of the Calendar service or application like Google Calendar or Outlook. This format is defined in RFC 5545. Creating iCalendar files can be done in Python using the icalendar
package. I’ve outlined a few example scenarios below. The package documentation has more details on usage.
Installing the package
pip install icalendar
Other methods are available in the official documentation.
Creating a calendar and adding an event
from icalendar import Calendar, Event
import datetime as dt
import zoneinfo
cal = Calendar()
cal.add("prodid", "-//Pesky Potato//pesky.moe//EN")
cal.add("version", "2.0")
cal.add("summary", "Newspaper schedule")
event = Event()
event.add('dtstart', dt.datetime(2025, 1, 2, 5, 30, 0, tzinfo=zoneinfo.ZoneInfo('Europe/Berlin')))
event.add('dtend', dt.datetime(2024, 1, 2, 6, 15, 0, tzinfo=zoneinfo.ZoneInfo('Europe/Berlin')))
event.add('summary', "Morning paper drop-off")
cal.add_component(event)
with open("example.ics", "wb") as f:
f.write(cal.to_ical())
Calendar()
is the highest component type which can contain subcomponents. A product identifier (PRODID), version and summary is added to the calendar. Both product identifier and version are required properties for a calendar.
An Event()
sub-component is created, dtstart
and dtend
properties are then added to signify the start and end times of the event. A summary is added to the event acting as the title and a description
can also be added for longer text.
The event is added to the parent calendar by calling add_component()
.
The calendar is then written to file using to_ical()
which returns a bytes object.
Setting a name for the calendar
Using summary
on the calendar component doesn’t set the name of the calendar when I tested this on Outlook and Google Calendar. However, after looking at a few .ics
files I saw setting the X-WR-CALNAME
was used to define the name. Wikipedia lists other similar “private software extension” to the defined spec all beginning with X-
.
from icalendar import Calendar
cal = Calendar()
cal.add("X-WR-CALNAME", "Garbage collection schedule")
Create an all-day event
To create an all-day event set dtstart
to the day and dtend
to the next day. Omit time from the values.
from icalendar import Event
import datetime as dt
event_day = dt.date(2025, 1, 4)
event.add("summary", "All day thing")
event.add("dtstart", event_day)
event.add("dtend", event_day + dt.timedelta(days=1))
Adding events every Tuesday on an even week
This example is not an iCalendar specific example but uses Python’s datetime
library to get even weeks between a start and end date and add an iCalendar event for Tuesdays of even weeks.
cal = Calendar()
start_date = dt.datetime(2024, 12, 30, tzinfo=zoneinfo.ZoneInfo('Europe/Berlin')) # Start of week 1
end_date = dt.datetime(2025, 12, 31, tzinfo=zoneinfo.ZoneInfo('Europe/Berlin'))
current_date = start_date
while current_date <= end_date:
if current_date.isocalendar().week % 2 == 0:
garbage_day = current_date + dt.timedelta(days=1)
event = Event()
event.add("summary", "Collect garbage")
event.add("dtstart", garbage_day)
cal.add_component(event)
current_date = current_date + dt.timedelta(days=7)
Other features
The Python package comes with a CLI tool, that can be used to inspect iCalendar files, more details can be found in the documentation.
LearnPython has more examples of using the package including how to read existing files in Python.
Finally, a note on hosting the iCalendar file if you aren’t just importing it directly, James Doc has documented ways to make this available through a click-able link for Outlook, Google Calendar, and Apple Calendar.