ics-calendar · Browser tool
ICS Calendar Builder
Fill in an event, add a repeat rule if it needs one, and download an .ics file that Google Calendar, Outlook and Apple Calendar will accept. You can also paste an existing file to see what is inside it.
Event
People and repeat
Repeat
Generated file
Read or merge an existing file
Paste the contents of an .ics file, or pick one from disk. Its events are listed below and can be folded into the download above.
What this does
An .ics file is plain text in the iCalendar format described by RFC 5545. It looks simple enough to write by hand, which is how most broken calendar files come about. A file that opens fine in one reader can be silently rejected by another because of a rule that is easy to miss.
The rules this page follows
Lines end with a carriage return and a line feed, not a bare line feed. Long lines are folded at 75 octets — counted in UTF-8 bytes, not characters, so an accented name shortens the line — and the continuation begins with a single space that the reader strips again. Inside text fields a backslash, comma or semicolon is escaped with a backslash, and a line break becomes the two characters \n; an unescaped comma in a location turns one value into two and is a common cause of truncated addresses. Every event carries a UID that is unique forever, generated here from the browser's cryptographic random source, because a repeated UID makes a calendar overwrite an earlier event instead of adding a new one. DTSTAMP is always written in UTC with a trailing Z, since it records when the file was produced rather than when the meeting happens.
Time zones, honestly
Three modes are offered. Floating time has no zone at all and lands at the same wall-clock time wherever it is opened, which suits a personal reminder and nothing else. UTC is unambiguous and right for anything crossing borders. A named zone writes TZID=Europe/Berlin and the wall-clock time; established calendar clients resolve that name from their own time zone database. Because this page has no zone database of its own, the VTIMEZONE block it writes alongside is a stub carrying the single offset in force at the event start. Clients that trust the name ignore it. A client that relies only on the stub will read a recurring series that crosses a daylight-saving change one hour out. If that matters, use UTC.
All-day events
An all-day event uses VALUE=DATE and its end date is exclusive: a meeting on the 14th ends on the 15th. Forgetting that is why single-day events sometimes import as zero-length. The page does the arithmetic for you and shows the result in the generated file.