ICalendar
iCalendar (.ics) event format — the universal standard (RFC 5545) for exchanging calendar events, scheduling, and time-based data between applications.
You are a file format specialist with deep expertise in the iCalendar format (RFC 5545). You understand the component model (VCALENDAR, VEVENT, VTODO, VJOURNAL, VALARM, VTIMEZONE), property syntax with parameters, recurrence rules (RRULE, EXDATE, RDATE), timezone handling, attendee/organizer scheduling, and the CalDAV synchronization protocol. You can advise on creating, parsing, validating, and troubleshooting .ics files across Google Calendar, Apple Calendar, Outlook, and other calendar applications. ## Key Points - **VCALENDAR**: Top-level container (required). - **VEVENT**: Calendar event (meetings, appointments, all-day events). - **VTODO**: Task or to-do item with optional due date and completion status. - **VJOURNAL**: Journal entry or note. - **VFREEBUSY**: Free/busy time information. - **VTIMEZONE**: Timezone definition. - **VALARM**: Alarm/reminder (nested inside VEVENT or VTODO). - Lines are separated by CRLF (`\r\n`). - Lines longer than 75 octets should be folded (continued on next line with leading space/tab). - Property values are separated from names by `:`. - Parameters are separated by `;` — e.g., `DTSTART;TZID=America/New_York:20250315T100000`. - Text values escape commas, semicolons, backslashes, and newlines: `\,` `\;` `\\` `\n`.
skilldb get file-formats-skills/ICalendarFull skill: 341 linesYou are a file format specialist with deep expertise in the iCalendar format (RFC 5545). You understand the component model (VCALENDAR, VEVENT, VTODO, VJOURNAL, VALARM, VTIMEZONE), property syntax with parameters, recurrence rules (RRULE, EXDATE, RDATE), timezone handling, attendee/organizer scheduling, and the CalDAV synchronization protocol. You can advise on creating, parsing, validating, and troubleshooting .ics files across Google Calendar, Apple Calendar, Outlook, and other calendar applications.
iCalendar — Calendar Event Format
Overview
iCalendar (iCal) is a text-based format for exchanging calendar and scheduling information, standardized as RFC 5545 (2009, originally RFC 2445 in 1998). It is the universal format for calendar events — every major calendar application (Google Calendar, Apple Calendar, Outlook, Thunderbird) reads and writes .ics files. When you receive a meeting invitation by email, add an event from a website, or subscribe to a calendar feed, you're using iCalendar.
Core Philosophy
iCalendar (.ics) is the open standard for calendar data interchange, defined by RFC 5545. Its core purpose is enabling calendar events, to-dos, and free/busy information to move between different calendar applications — Google Calendar, Outlook, Apple Calendar, Thunderbird — without losing essential scheduling data. When you send a meeting invitation or subscribe to a calendar feed, iCalendar is the format doing the work.
iCalendar's text-based format uses a property:value structure with component nesting (VCALENDAR containing VEVENT, VTODO, VFREEBUSY). This structure is human-readable and debuggable with a text editor, which is valuable when troubleshooting calendar synchronization issues. However, the specification's complexity — recurring events, timezone handling, attendee management, and alarm definitions — means that robust iCalendar parsing and generation should always use a library rather than manual string manipulation.
Timezone handling is iCalendar's most error-prone area. Always use IANA timezone identifiers (America/New_York, Europe/London) rather than UTC offsets, and include VTIMEZONE components in your iCalendar output. Events specified with bare UTC offsets break when daylight saving time rules change. Use a well-maintained iCalendar library that handles timezone resolution correctly.
Technical Specifications
Syntax and Structure
iCalendar uses a line-oriented text format with BEGIN/END component blocks:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp//Calendar App//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Team Events
X-WR-TIMEZONE:America/New_York
BEGIN:VTIMEZONE
TZID:America/New_York
BEGIN:DAYLIGHT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/New_York:20250315T100000
DTEND;TZID=America/New_York:20250315T110000
DTSTAMP:20250301T120000Z
UID:unique-event-id-12345@example.com
SUMMARY:Team Standup
DESCRIPTION:Daily standup meeting.\nPlease join on time.
LOCATION:Conference Room B / https://zoom.us/j/123456
ORGANIZER;CN=Alice:mailto:alice@example.com
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Bob:mailto:bob@example.com
ATTENDEE;ROLE=OPT-PARTICIPANT;PARTSTAT=TENTATIVE;CN=Charlie:mailto:charlie@example.com
STATUS:CONFIRMED
CATEGORIES:Meeting,Team
PRIORITY:5
SEQUENCE:0
TRANSP:OPAQUE
BEGIN:VALARM
TRIGGER:-PT15M
ACTION:DISPLAY
DESCRIPTION:Meeting starts in 15 minutes
END:VALARM
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20250401
DTEND;VALUE=DATE:20250402
UID:all-day-event-67890@example.com
SUMMARY:Company Holiday
DESCRIPTION:Office closed for spring holiday
TRANSP:TRANSPARENT
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1MO
END:VEVENT
BEGIN:VTODO
DTSTAMP:20250301T120000Z
UID:todo-item-001@example.com
SUMMARY:Prepare quarterly report
DUE:20250320T170000Z
PRIORITY:1
STATUS:IN-PROCESS
PERCENT-COMPLETE:50
END:VTODO
END:VCALENDAR
Components
- VCALENDAR: Top-level container (required).
- VEVENT: Calendar event (meetings, appointments, all-day events).
- VTODO: Task or to-do item with optional due date and completion status.
- VJOURNAL: Journal entry or note.
- VFREEBUSY: Free/busy time information.
- VTIMEZONE: Timezone definition.
- VALARM: Alarm/reminder (nested inside VEVENT or VTODO).
Key Properties
| Property | Description | Example |
|---|---|---|
| DTSTART | Event start date/time | 20250315T100000Z |
| DTEND | Event end date/time | 20250315T110000Z |
| DURATION | Event duration (alternative to DTEND) | PT1H30M |
| SUMMARY | Event title | Team Meeting |
| DESCRIPTION | Detailed description | Agenda: review sprint goals |
| LOCATION | Event location | Room 42 |
| UID | Globally unique identifier (required) | uuid@domain.com |
| RRULE | Recurrence rule | FREQ=WEEKLY;BYDAY=MO,WE,FR |
| ORGANIZER | Meeting organizer | mailto:alice@example.com |
| ATTENDEE | Meeting participant | mailto:bob@example.com |
| STATUS | Event status | CONFIRMED, CANCELLED, TENTATIVE |
| SEQUENCE | Revision sequence number | 0 (incremented on updates) |
Recurrence Rules (RRULE)
# Every weekday at 9am
RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
# Monthly on the 15th, 10 occurrences
RRULE:FREQ=MONTHLY;BYMONTHDAY=15;COUNT=10
# Every 2 weeks on Tuesday and Thursday until end of year
RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,TH;UNTIL=20251231T235959Z
# Last Friday of every month
RRULE:FREQ=MONTHLY;BYDAY=-1FR
# Yearly on March 15
RRULE:FREQ=YEARLY;BYMONTH=3;BYMONTHDAY=15
# Exceptions to recurrence
EXDATE:20250401T100000Z,20250408T100000Z
Format Rules
- Lines are separated by CRLF (
\r\n). - Lines longer than 75 octets should be folded (continued on next line with leading space/tab).
- Property values are separated from names by
:. - Parameters are separated by
;— e.g.,DTSTART;TZID=America/New_York:20250315T100000. - Text values escape commas, semicolons, backslashes, and newlines:
\,\;\\\n. - Date-times:
YYYYMMDDTHHMMSS(local),YYYYMMDDTHHMMSSZ(UTC), or with TZID parameter. - All-day events use
VALUE=DATE:DTSTART;VALUE=DATE:20250315.
How to Work With It
Python
# icalendar library
from icalendar import Calendar, Event, vDatetime
from datetime import datetime, timedelta
import pytz
# Create
cal = Calendar()
cal.add('prodid', '-//My App//EN')
cal.add('version', '2.0')
event = Event()
event.add('summary', 'Team Meeting')
event.add('dtstart', datetime(2025, 3, 15, 10, 0, tzinfo=pytz.timezone('US/Eastern')))
event.add('dtend', datetime(2025, 3, 15, 11, 0, tzinfo=pytz.timezone('US/Eastern')))
event.add('uid', 'unique-id@example.com')
event.add('location', 'Conference Room')
cal.add_component(event)
with open('event.ics', 'wb') as f:
f.write(cal.to_ical())
# Parse
with open('event.ics', 'rb') as f:
cal = Calendar.from_ical(f.read())
for event in cal.walk('VEVENT'):
print(event.get('summary'))
print(event.get('dtstart').dt)
# Expand recurring events
from recurring_ical_events import of
events = of(cal).between(
datetime(2025, 1, 1), datetime(2025, 12, 31)
)
JavaScript
// ical.js (Mozilla)
import ICAL from 'ical.js';
const parsed = ICAL.parse(icsString);
const comp = new ICAL.Component(parsed);
const events = comp.getAllSubcomponents('vevent');
for (const vevent of events) {
const event = new ICAL.Event(vevent);
console.log(event.summary, event.startDate.toString());
// Handle recurrence
if (event.isRecurring()) {
const iterator = event.iterator();
let next;
while ((next = iterator.next()) && next.compare(endDate) < 0) {
console.log('Occurrence:', next.toString());
}
}
}
// Create
const cal = new ICAL.Component(['vcalendar', [], []]);
cal.addPropertyWithValue('version', '2.0');
const vevent = new ICAL.Component('vevent');
vevent.addPropertyWithValue('summary', 'Meeting');
vevent.addPropertyWithValue('dtstart', ICAL.Time.fromDateString('2025-03-15'));
cal.addSubcomponent(vevent);
console.log(cal.toString());
Subscribing to Calendar Feeds
# Calendar subscription URLs (webcal:// or https://)
webcal://example.com/calendar.ics
# Google Calendar public URL
https://calendar.google.com/calendar/ical/{cal_id}/public/basic.ics
# Apple Calendar, Outlook, Thunderbird all support webcal:// subscriptions
# Calendars are polled periodically (typically every 15-60 minutes)
Validation
# ical-validator (npm)
npx ical-validator event.ics
# Python
from icalendar import Calendar
try:
Calendar.from_ical(open('event.ics', 'rb').read())
print("Valid")
except Exception as e:
print(f"Invalid: {e}")
# Online: icalendar.org/validator.html
Common Use Cases
- Meeting invitations: Email-attached
.icsfiles for scheduling. - Calendar subscriptions: Public event feeds, sports schedules, holidays.
- Event registration: "Add to Calendar" buttons on websites and tickets.
- Scheduling protocols: CalDAV (WebDAV-based calendar sync), iTIP, iMIP.
- Room booking: Exchange/Google Workspace resource scheduling.
- Public calendars: Government meetings, school schedules, concert dates.
- Time tracking: Export/import time entries between applications.
Pros & Cons
Pros
- Universal support — works with every major calendar application.
- Open standard (RFC 5545) — well-documented, stable, vendor-neutral.
- Text-based and human-readable — can be created/edited in a text editor.
- Rich recurrence rules — complex patterns (3rd Thursday of every month).
- Timezone support — proper handling of DST transitions.
- Alarms/reminders — built-in notification support.
- Calendar subscription — live feeds via URL.
Cons
- Verbose syntax — simple events require many lines of boilerplate.
- Recurrence rule complexity — RRULE spec is notoriously hard to implement correctly.
- Timezone handling is difficult — VTIMEZONE definitions are lengthy.
- No built-in authentication for calendar feeds (relies on transport layer).
- Line folding at 75 octets is fragile and easily broken by text editors.
- Inconsistent implementation across calendar apps — edge cases vary.
- Limited rich text — DESCRIPTION is plain text (some apps support HTML via X-ALT-DESC).
- Encoding issues — not all apps handle UTF-8 correctly.
Compatibility
| Application | Import | Export | Subscribe |
|---|---|---|---|
| Google Calendar | Yes | Yes | Yes |
| Apple Calendar | Yes | Yes | Yes |
| Outlook | Yes | Yes | Yes |
| Thunderbird | Yes | Yes | Yes |
| Yahoo Calendar | Yes | Yes | Yes |
| Fastmail | Yes | Yes | Yes |
| Library | Language |
|---|---|
| icalendar | Python |
| ical.js | JavaScript |
| ical4j | Java |
| icalendar-ruby | Ruby |
| sabre/vobject | PHP |
MIME type: text/calendar. File extension: .ics (also .ical, .ifb for free/busy).
Related Formats
- vCard (.vcf): Contact data format — same content-line syntax as iCalendar.
- CalDAV: WebDAV protocol for calendar access and synchronization.
- jCal (RFC 7265): JSON representation of iCalendar data.
- xCal (RFC 6321): XML representation of iCalendar data.
- hCalendar: Microformat for embedding events in HTML.
- Schema.org Event: JSON-LD structured data for events on web pages.
- iCalendar Transport (iTIP): Protocol for scheduling messages (RFC 5546).
Practical Usage
- "Add to Calendar" buttons on websites: Generate
.icsfiles server-side and serve them as downloads. Include SUMMARY, DTSTART, DTEND, LOCATION, and DESCRIPTION at minimum. Set the Content-Type totext/calendarand Content-Disposition to attachment. - Calendar subscription feeds: Host a dynamically generated
.icsfile at a stable URL for calendar subscriptions. UseMETHOD:PUBLISHand includeX-WR-CALNAMEfor the display name. Calendars poll every 15-60 minutes, so changes are not instant. - Timezone handling: Always include VTIMEZONE components or use UTC (
YYYYMMDDTHHMMSSZ) for unambiguous time representation. Floating times (no timezone or Z suffix) are interpreted in the user's local timezone, which causes confusion for multi-timezone events. - Recurrence rule testing: Test RRULE expansions with a library (Python
recurring_ical_events, JSical.js) before deployment. Complex rules with BYDAY, BYMONTH, and INTERVAL interact in non-obvious ways. Edge cases around DST transitions are particularly tricky. - Cancellation workflow: To cancel an event, send an updated .ics with the same UID, incremented SEQUENCE number, and
STATUS:CANCELLED. Do not simply delete the event -- recipients need the cancellation notice to remove it from their calendars.
Anti-Patterns
- Generating events without a globally unique UID: The UID property is required and must be globally unique (e.g., UUID@yourdomain.com). Reusing UIDs causes calendar applications to overwrite unrelated events or fail to distinguish between different events.
- Using floating times for events with remote attendees: Floating times (no timezone specified) are rendered in each user's local timezone. A "3:00 PM" meeting appears at 3 PM for everyone regardless of their timezone. Always specify TZID or use UTC for events involving multiple timezones.
- Forgetting CRLF line endings: The iCalendar spec requires
\r\n(CRLF) line endings, not just\n(LF). Some calendar applications reject or misparse files with Unix-style line endings. Always write with CRLF when generating .ics files. - Breaking line folding at arbitrary positions: Lines longer than 75 octets must be folded with a CRLF followed by a single space or tab. Breaking mid-multibyte-character or not adding the continuation whitespace creates corrupt files that parsers reject.
- Embedding HTML in DESCRIPTION without using X-ALT-DESC: The DESCRIPTION property is plain text only. Putting raw HTML in DESCRIPTION displays HTML tags as visible text in most calendar apps. Use the non-standard
X-ALT-DESC;FMTTYPE=text/html:property for HTML content.
Install this skill directly: skilldb add file-formats-skills
Related Skills
3MF 3D Manufacturing Format
The 3MF file format — the modern replacement for STL in 3D printing, supporting colors, materials, multi-object assemblies, and precise manufacturing data in a single package.
7-Zip Compressed Archive
The 7z archive format — open-source high-ratio compression using LZMA2, with strong AES-256 encryption, solid archives, and multi-threading support.
AAC (Advanced Audio Coding)
A lossy audio codec standardized as part of MPEG-2 and MPEG-4, designed to supersede MP3 with better quality at equivalent or lower bitrates.
AC3 (Dolby Digital)
Dolby's surround sound audio codec used in cinema, DVD, Blu-ray, and broadcast television for multichannel 5.1 audio delivery.
AI Adobe Illustrator Format
AI is Adobe Illustrator's native vector graphics file format, used for
AIFF (Audio Interchange File Format)
Apple's uncompressed audio format storing raw PCM data, serving as the Mac equivalent of WAV for professional audio production.