iCal is a simple format for sharing calendar, event and todo list information between applications. It is widely supported by many many applications.

I have recently been hacking on a couple of projects which required me to implement the format, and during this I hit on a couple of less well documented gotchas.

So, I’ve jotted them down here in order to hopefully save you some time…

  • Line endings: The specification says that line endings should be CRLF only, and some less tolerant clients puke if they’re not.
  • No blank lines: Ensure that your output contains no blank lines, again some clients with puke or interpret these as the end of the file.
  • End in .ics (the biggy): This is important if you dynamically generate an iCal feed for use with Google Calendar. You should set header type appropriately, e.g.

    header("Content-Type: text/calendar");
    header('Content-Disposition: attachment; filename="calendar.ics"');

    But critically, if all your entries are showing up only as “Busy”, you must also end the URL you pass to Google calendar as http://foo.com/bar/whatever.ics

You may find one of these validator tools useful too.

Hope that helps!

Image “Calendar Logo” by Quadmod

8 thoughts on “iCAL Gotchas

  1. Hi Marcus, no matter what I try, events don’t delete from Google Calendar or Outlook, even when they validate correctly and contain all the required information. Any further tips or links?

  2. Google I think are in the middle of moving and consolidating their APIs, and I get the feeling they’re moving to a different way of doing things. Plus, I think they employ some rather aggressive caching on events in the feed (to avoid polling constantly).

    https://productforums.google.com/forum/#!topic/calendar/qlP0CMwtBws

    You could try updating the feed with the same UID, but marking it as cancelled: https://en.wikipedia.org/wiki/ICalendar#Events_.28VEVENT.29 – not quite the same thing, but could be a workaround.

  3. Thanks for getting back to me so quickly. I’ve been attempting to update by setting Method and Status in the file, using the same UID, but an incremented sequence. But nothing ever works, sadly.

Leave a Reply