iCalendar is an Internet standard format for exchanging calendar data. Many calendar applications can export and import data in iCalendar format. iCalendar data is also often sent as email attachments. iCalendar data usually uses the .ics file extension, and is sent with the ‘text/calendar’ MIME type in email. (See Mail Miscellany, for more information on MIME and email attachments.)
The diary-icalendar package allows you to make use of iCalendar
data with the Emacs diary. You can import and export data between
iCalendar format and your Emacs diary file, and also display iCalendar
data directly in the diary.
The following commands will import iCalendar data to your diary file:
diary-icalendar-import-file ¶Imports an iCalendar file to an Emacs diary file.
diary-icalendar-import-buffer ¶Imports iCalendar data from the current buffer to an Emacs diary file.
diary-icalendar-import-buffer is also suitable for importing
iCalendar data from email attachments. For example, with the Rmail mail
client, you could use:
(add-hook 'rmail-show-message-hook #'diary-icalendar-import-buffer)
Diary import depends on a number of user-customizable variables, which
are in the diary-icalendar-import customization group. You can
review and customize these variables with M-x customize-group.
See Customization Groups.
iCalendar data is grouped into components which represent calendar events (the VEVENT component), tasks (VTODO), and other text data (VJOURNAL). Because these components contain different types of data, they are imported by different functions, determined by the following variables:
diary-icalendar-vevent-format-function ¶Function to format VEVENT components for the diary.
diary-icalendar-vjournal-format-function ¶Function to format VJOURNAL components for the diary.
diary-icalendar-vtodo-format-function ¶Function to format VTODO components for the diary.
You can customize the format of the imported diary entries by writing your own formatting functions. It is convenient (but not required) to express such functions as templates called skeletons.
For example, suppose you only want to import the date, time, summary, and location of each calendar event, and to write them on a single line like:
2025/11/11 Summary @ Some Location
Then you could write the import formatting function as a skeleton and
set it to the value of diary-icalendar-vevent-format-function as
follows:
(require 'skeleton)
(defun simple-vevent (_)
"Format a VEVENT summary and location on a single line"
(skeleton-insert
'(nil
ical-start-to-end & " " & ical-summary & " "
(when ical-location "@ ") & ical-location "\n")))
(setopt diary-icalendar-vevent-format-function #'simple-vevent)
The variables ical-start-to-end, ical-summary and
ical-location in this example are dynamically bound to
appropriate values when the skeleton is called. See the docstring of
diary-icalendar-vevent-format-function for more information.
Any errors encountered during import will be reported in a buffer named
*icalendar-errors*. You can review these errors with the
next-error command. See Compilation Mode. If you regularly
need to import malformed iCalendar data, there are several hooks
available for this purpose; see the icalendar-parser
customization group.