How the iCalendar specification works and how to create .ics files


What can iCalendar do?

The unification of work with calendars has gone through several stages:

  • The first step was taken in 1996 by the Versit Consortium, which developed the vCalendar standard.

  • In 1998, the IETF published a standard RFC 2445based on the experience of using vCalendar.

  • In 2009, RFC 2445 was replaced by RFC 5545 and its extension iCalendar by the iTIP protocol described in RFC 5546.

  • In 2012 RFC 6638 added scheduling support to CalDAV based on the iTIP protocol.

The advantages of this format include:

  • Versatility. Now iCalendar is used by all modern calendar applications and services: Microsoft Outlook, Google Calendar, Apple Calendar, etc. It provides them with compatibility and allows synchronization.

  • Ease of data exchange. Synchronization between different applications occurs through the export and import of .ics files.

  • Flexibility. iCalendar supports complex use cases: recurring events, tasks with priorities, notifications.

  • Support for CalDAV protocol. Allows you to organize work with calendar data in distributed systems, providing synchronization and event management between different devices and applications via HTTP requests to a server that supports CalDAV. I will tell you more about this below.

It should be taken into account that when creating complex recurring events with a large number of exceptions, the structure of the ics file will become more complex and the file size will increase.

What is included in the calendar file

Example of .ics file:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//id//NONSGML v1.0//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
UID:12345678-1234-1234-1234-123456789012
DTSTART:20240816T150000Z
SUMMARY:title
DESCRIPTION:description
END:VEVENT
END:VCALENDAR

.ics files use text data and include components, each of which serves a different purpose. They are:

  • VJOURNAL stores entries in a journal. It can be used to keep personal notes, record events during the day.

  • VEVENT describes events or meetings and includes start and end date and time, location, organizer and participant information, it may also contain repeat information (RRULE), event status, category, etc. It is used to create events in the calendar, send and receive responses.

  • VTODO describes the parameters of the task: deadline, priority, current status and progress.

  • VALARM configures notifications related to VEVENT or VTODO. It allows you to create an alert, configure the type, time and frequency of notification.

  • VFREEBUSY used to describe periods of free or busy time.

Example of use

In distributed systems, client applications—for example, calendars on mobile devices or desktops—work with events on servers via the CalDAV protocol and maintain full compatibility with the iCalendar format.

Google Calendar uses CalDAV to synchronize with external clients that support this protocol. And the Google Calendar API, although it uses its own data structure for working with events, supports the iCalendar standard. This makes it possible to synchronize with clients that work only with iCalendar.

Microsoft Outlook supports import and export of .ics files, which allows you to exchange events with other calendar systems. Microsoft Exchange Server uses .ics files to exchange events and tasks between Outlook and other clients.

How to work with .ics files

The .ics file has a text type and mime-type of text/calendar. In the simplest version, it can be created manually in a text editor and checked for errors using any third-party validatorsupporting RFC 5545.

Another option for creating .ics files is to use ready-made libraries. For JavaScript, I found two:

  • icalendar.js — abandoned project, last edited ten years ago. Functions only in Nodejs, requires polyfills to work in the browser.

  • rrule.js — a more lively project specializing in generating and managing repeating events (RRULE). This library is intended for use in both Node.js and browsers, but additional libraries may be required to generate full .ics files. The library is 687 KB in size and has a dependency on the tslib package.

In his pet project I use the RFC 5545 standard. Since the ready-made library options did not suit me, I implemented the creation of ics files in my own library ical browser in TypeScript. Unlike rrule.js and icalendar.js, the library also works in browsers without creating heavy dependencies. I have many plans for its improvement – write to me in a personal message if you want to help or need some additional functionality.

Example of working with ical-browser

First, let's install the package:

npm install ical-browser

Let's connect the library to our project that supports ESM modules. We will work with the Event, Todo, Journal and Alarm types:

import { todo as createTodo,
  event as createEvent,
  journal as createJournal,
  alarm as createAlarm,
  default as icalendar, } from 'ical-browser'

// Раньше можно было использовать любое значение, но для повышения безопасности требуется уникальное значение идентификатора, например uuidv1
const uid = 'c7614cff-3560-4a00-9152-d25cc1fe077d',

const event = createEvent({
    uid,
    location: 'Online',
    geo: [37.5739497,-85.7399606],
    summary: 'Event summary',
    description: 'Event description',
    stamp: new Date(),
    start: new Date('2024-01-01T10:10:00.611Z'),
    end: new Date('2024-01-02T10:12:00.611Z'),
    // Прикладываем документ в формате base64. В данном случае это будет пиксель в формате gif
    attach: [
      'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQEAAAAACwAAAAAAQABAAACAkQBADs=",
    ],
    organizer: "Jane Doe',
    attendee: 'CN=John Smith:mailto:john.smith@example.com',
    url: new URL('https://example.com#event'),
})

const todo = createTodo({
    uid,
    stamp: new Date(),
    due: new Date(),
    summary: 'Task summary',
    description: 'Task description',
    priority: 1,
    status: 'CONFIRMED',
})

const journal = createJournal({
    uid,
    stamp: new Date(),
    due: new Date(),
    summary: 'Journal summary',
    description: 'Journal description',
})

const alarm = createAlarm({
    uid,
    trigger: '-PT5M',
    description: 'Reminder',
    action: 'DISPLAY',
})

// Cклеиваем данные и генерируем файл
const str = icalendar('ID’, { event, todo, journal, alarm })
const file = new File([new TextEncoder().encode(str)], 'example.ics', {
  type: 'text/calendar',
})

After launching, we try to open the created file:

We will see a new event in Apple Calendar

We will see a new event in Apple Calendar

It is important to take into account that the time is taken with the time zone specified. Therefore, in my example, the value of new Date('2024-01-01T10:10:00.611Z') for Moscow will be 13:10.

Summary

iCalendar is a flexible and powerful standard for working with calendar data, supported by most modern applications and services. .ics files are easy to create and import into all the most popular time management applications.

I hope my article helped you better understand the iCalendar standard and how to integrate it into your projects. If you have any questions or have something to add to the article, please write in the comments.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *