I've almost finished developing a library to import ICS (ical) data, and
I am looking for a few more Beta testers.
I'm also interested in more test data, so even if you don't want to test
it but have publically accessible calendar files (or others that you are
willing to send me), I'd be grateful - please email me off-list with
either a URL or the actual data to test against.
It is (afaik) complete - everything in the relevant RFC is handled
(afaik) correctly. It's been moderately well tested - I'm particularly
interested in testing by anyone who has calendar files generated by apps
other than Apple's iCal or Google Calendar (that's the two I have ready
access to). The only remaining item is to add more timezone info to the
built-in timezones - and I hope to build that up from Beta testers or
peopl ewho respond to my request for more test data.
I'd like to say a quick "Thanks" to Dan Friedman, both for coming up
with the idea by originally asking for a library like this on this list,
and for being a great helper with testing.
The library will be released as a Commercial-only (i.e. locked stack)
I feel I *should* release a GPL version - but I have to admit to being
wary of making the source code widely available. So, initially at least,
the GPL version (which will also of course be the Trial version), will
be released as GPL, but will use a Web service to do the real work - so
an Internet connection will be required. The web server uses the full
library, so should produce exactly the same results as the commercial
one - just slightly less conveniently, and slightly more slowly. This
will allow Community Edition users to use the library, and anyone to
test it / play with it.
It comes with a couple of demo / sample stacks so you can easily see how
to use it.
If you are interested in testing (or simply playing with ti), please
email me off-list.
Initial draft documentation is available at
The library is intended to aid in reading ics (ical) files, created
according to rfc5545.
The library includes a number of small utility functions, and two
significant functions which provide all the main capabilities.
These allow you to import a ".ics" (aka ical) file, and build a calendar
array of the data, and subsequently to "expand" a calendar
to extract all events (and instances of events) which impact a specific
"period of interest" in time. Note that since many calendars
include open-ended recurring events, it is not possible to just "expand"
a calendar - it MUST be for a limited time period.
The parameters and results of these functions are described below in the
detailed functionality section. Here we have simply a
description of the calendar array that is created.
Calendar array definition
All data from the ics file is maintained in the calendar array. Note
that (although LC is generally case insensitive), I have followed
a convention on the use of case for array elements - all data from the
ics file is stored using an upper case key (actually, using the
case present in the ics file - which is upper case) using "-" (minus
sign) to separate 'words' in the key; and all data generated by
the library is stored in a lower-case named key, using "_" (underscore)
as a word separator. So for example, an event will generally
have its start date as stored in the ics file
CalA["events"]["DTSTART"] will have 20131025T080000Z
CalA["events"]["start_date"] will have 20131025
CalA["events"]["start_date_time"] will have 20131025.060000
(NB even though the event specifies a date+time, "start_date" is
just the date.
"start_date_time" has both date and time - and it has been
adjusted to the correct local timezone).
Since all the data in the ics file is fully described by the RFC, I have
not repeated all that info here, but instead
only described a small subset of the original data, only those which I
think are most often likely to be used.
CalA["X-WR-TIMEZONE"] :: the default timezone for any event which
doesn't specify its own time zone
CalA["default_time_zone"] :: the ultimate default timezone specified by
the app, in case X-WR-TIMEZONE isn't set
CalA["event_count"] :: the number of events in the calendar
CalA["timezones"] :: array of timezone info
[<name>] :: the name of the timezone, and
it contains an array ofdata about it
["TZID"] :: the name of the
TZ - should be the same as the key <name>
a sorted CR-delimited list of dates when clocks change
has the decimal-date/time of the change, and the offset (from UTC)
before, and after, the change
["STANDARD"] For each of
daylight and standard time periods, a numerically indexed array
of event-like info specifying the rules for changing between the two
CalA["events"] :: a numerically-indexed list of event structures (i.e. 1
Each event structure (i.e. within ["events"][N] or
["timezones"][<name>][<period>][N]) has the following data
...["SUMMARY"] :: the short summary description of the event
...["start_date"] :: the date on which the event starts
...["start_date_time"] :: the date+time the event starts (IF it is a
...["whole_day"] :: boolean true if the event is a 'whole day' event
...["end_date"] and ...["end_date_time"] same as start_date,
start_date_time above, but for the end of the event
...["days_delta_to_end"] :: the number of days from start_date to end_date
...["recur_rule"] :: an array (numericaly indexed - can be multiple of
them) holding the expanded info from any RRULE
...["list_of_rdates"] ;; a CR delimited list of dateItems for the
dates specified by an RDATE entry
Dates, Times, etc.
The interface to the library uses two main styles of dates/times. One is
LC's "dateItems" (q.v.) format, the other is a
8-char date format (YYYYMMDD) and/or 15 character date+time
(YYYYMMDD.HHMMSS). I wanted to choose a format which
satisfied as many as possible of the following criteria:
1. It should be easy to compare two dates or date/times.
2. It should be easy to do arithmetic (add days, find difference between
3. It should be easy to work with.
One obvious choice would have been Julian days / dates; they are
comparable and easy for arithmetic, but
I found them so hard to deal with ( is 2456590.89948 today or tomorrow ?
They YYYYMMDD.HHMMSS format dates are comparable and very easy to use.
You can't do arithmetic on them easily,
but that is only needed in a couple of places - hence that was the
Note the dates and date/times within the ICS files are in a different
(again) format, YYYYMMDD'T'HHMMSS(Z)
using the letter 'T' where I used a ".", and optionally having a 'Z' on
the end to indicate UTC time. So if you look at the
calendar info, you will see that format of dates.