Programming with iCalendar

Since iCalendar is an important data format, it’s worth looking a bit more at how to manipulate it in PHP and Python.

[Note]Note

 The hCalendar microformat is designed to express the same information as iCalendar but in a form that is embeddable in HTML and RSS. See Chapter 18 on microformats for how to use and create hCalendar.

Python and iCalendar

A good Python module to use is iCalendar:

http://codespeak.net/icalendar/

As of this writing, the latest version is 1.2. You download this code here:

http://codespeak.net/icalendar/iCalendar-1.2.tgz

To run a basic test of iCalendar interoperability, I created an event on Apple iCal and e-mailed it to myself. On my notebook, the filename is as follows:

D:\Document\Docs\2007\05\iCal-20070508-082112.ics

What’s actually in the file?

            BEGIN:VCALENDAR
            VERSION:2.0
            X-WR-CALNAME:open house at the Academy
            PRODID:-//Apple Computer\, Inc//iCal 2.0//EN
            CALSCALE:GREGORIAN
            METHOD:PUBLISH
            BEGIN:VTIMEZONE
            TZID:US/Pacific
            LAST-MODIFIED:20070508T152112Z
            BEGIN:DAYLIGHT
            DTSTART:20070311T100000
            TZOFFSETTO:-0700
            TZOFFSETFROM:+0000
            TZNAME:PDT
            END:DAYLIGHT
            BEGIN:STANDARD
            DTSTART:20071104T020000
            TZOFFSETTO:-0800
            TZOFFSETFROM:-0700
            TZNAME:PST
            END:STANDARD
            END:VTIMEZONE
            BEGIN:VEVENT
            DTSTART;TZID=US/Pacific:20070510T190000
            DTEND;TZID=US/Pacific:20070510T200000
            SUMMARY:open house at the Academy
            UID:AAE603F6-A5A1-4E11-91CF-E6B06649A756
            ORGANIZER;CN="Raymond Yee":mailto:rdhyee@yahoo.com
            SEQUENCE:6
            DTSTAMP:20070508T152047Z
            END:VEVENT
            END:VCALENDAR
         

Now, I want to read it in using Python. Let’s also consult the documentation to build a simple example:[256]

            from icalendar import Calendar
            fname = r'D:\Document\Docs\2007\05\iCal-20070508-082112.ics'
            cal = Calendar.from_string(open(fname,'rb').read())
            ev0 = cal.walk('vevent')[0]
            print ev0.keys()
            print "summary: ", str(ev0['SUMMARY'])
            print "start:", str(ev0['DTSTART'])
            # ev0['DTSTART'] is datetime.date() object
            print "end:", str(ev0['DTEND'])
         

If you run it, you get this:

            ['DTSTAMP', 'UID', 'SEQUENCE', 'SUMMARY', 'DTEND', 'DTSTART', 'ORGANIZER']
            summary:  open house at the Academy
            start: 20070510T190000
            end: 20070510T200000
         

Another Python iCalendar library is vobject:

http://vobject.skyhouseconsulting.com/usage.html

The following code shows how to use vobject to parse the same iCalendar file:

            import vobject
            fname = r'D:\Document\Docs\2007\05\iCal-20070508-082112.ics'
            cal = vobject.readOne(open(fname,'rb').read())
            event = cal.vevent
            print event.sortChildKeys()
            print "summary: ", event.getChildValue('summary')
            print "start:", str(event.getChildValue('dtstart'))
            # event.getChildValue('dtstart') is datetime.date() object
            print "end:", str(event.getChildValue('dtend'))
         

PHP and iCalendar

You can download iCalcreator, a PHP library for parsing and creating iCalendar files, here:

http://www.kigkonsult.se/iCalcreator/index.php

The module is documented here:

http://www.kigkonsult.se/iCalcreator/docs/using.html

Here is some code using iCalcreator to read and parse the same iCalendar file from the previous section:

            <?php
            
            require_once 'iCalcreator/iCalcreator.class.php';
            
              $filename = 'D:\Document\Docs\2007\05\iCal-20070508-082112.ics';
            
              $v = new vcalendar(); // initiate new CALENDAR
              $v->parse($filename);
            
              # get first vevent
              $comp = $v->getComponent("VEVENT");
              
              #print_r($comp);
              $summary_array = $comp->getProperty("summary", 1, TRUE);
              echo "summary: ", $summary_array["value"], "\n";
            
              $dtstart_array = $comp->getProperty("dtstart", 1, TRUE);
              $dtstart = $dtstart_array["value"];
              $startDate = "{$dtstart["year"]}-{$dtstart["month"]}-{$dtstart["day"]}";
              $startTime = "{$dtstart["hour"]}:{$dtstart["min"]}:{$dtstart["sec"]}";
              
              $dtend_array = $comp->getProperty("dtend", 1, TRUE);
              $dtend = $dtend_array["value"];
              $endDate = "{$dtend["year"]}-{$dtend["month"]}-{$dtend["day"]}";
              $endTime = "{$dtend["hour"]}:{$dtend["min"]}:{$dtend["sec"]}";
              
              echo "start: ",  $startDate,"T",$startTime, "\n";
              echo "end: ",  $endDate,"T",$endTime, "\n";
            
            ?>
         

The output of the code is as follows:

            summary: open house at the Academy
            start: 2007-05-10T19:00:00
            end: 2007-05-10T20:00:00
         

I will use iCalcreator in the following section to convert iCalendar feeds into Google calendar entries.