AirInformation Blog

Keeping technology fun

Archive for the ‘development’ Category

Working with ical time zones

with 2 comments

This is a continuation of my saga to build an ical synchronisation service for Android.

The ical specification allows event date and times to be stored in one of three possible ways; UTC, time zone specific (eg GMT, EST, PST etc) and local. The standard Android calendar stores its event information in UTC. This means that events from an ical file need to be converted from one of the three possible representations into UTC.

I initially used the Joda Time java library to help manage time zone conversions but have now ditched it in favour of my own simpler algorithm. Joda Time is a feature rich and excellent library, but I think it’s overkill for the task that I needed it for.

The three possible representations of time in an ical file:

  • UTC – stands for Universal Coordinated Time is similar to GMT except that no daylight savings are ever applied. GMT varies from UTC + 0 in winter to UTC + 1 hour between Spring and Summer.
  • Time zone specific – date and time expressed for a particular time zone means the time as shown on a wallclock in that time zone. For example, the GMT time zone stands for Greenwich Mean Time whose standard time offset is zero except in Summer when it is +1 hour.
  • Local – events expressed in local time have the hour (and minutes) preserved as you move across time zones. What does that mean, I hear you ask? You might create a repeating event (and alarm reminder) in local time that wakes you up at 7am no matter which timezone you are currently in. As you move across time zones (in the US for example), your alarms should go off at 7am independently of the time zone you’re in.

In order to convert an event’s date and time into UTC, you need to “know” which time zone the event occurs in. This is a function of the TZID identifier which prefixes the date and time in an ical VEVENT (long lines “folded” over to the next line):


DTSTART;TZID="(GMT) Greenwich Mean Time - Dublin / Edinburgh / Lisbon / Lond
on":20100117T130000
DTEND;TZID="(GMT) Greenwich Mean Time - Dublin / Edinburgh / Lisbon / London
":20100117T140000

The time zone in this example is called “(GMT) Greenwich Mean Time – Dublin / Edinburgh / Lisbon / London”, and its standard offset from UTC is 0. This is given by the VTIMEZONE rule below:


BEGIN:VTIMEZONE
TZID:(GMT) Greenwich Mean Time - Dublin / Edinburgh / Lisbon / London
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETTO:-0000
TZOFFSETFROM:+0100
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T010000
TZOFFSETTO:+0100
TZOFFSETFROM:-0000
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE

The RRULE entries indicate the periods for standard and daylight savings. In the VTIMEZONE entry, standard time runs from the last Sunday in October to the last Sunday in March. And daylight savings run from the last Sunday in March to the last Sunday in October. The actual change over occurs at 2am in the morning (denoted by “DTSTART:16010101T020000”) in standard time and 1am in daylight time (denoted by “DTSTART:16010101T010000”).

As each VEVENT (event) entry in the ical file is encountered it needs to be converted into UTC in order to see whether it exists within the Android calendar If it does not exist it is added. If it exists then it is updated.

The conversion is an expensive calculation. However I have two optimisations that I apply:

  1. all events outside an unconverted date range are discarded
  2. UTC conversions can be optimised by the month of the event

The first optimisation uses the fact that ical dates are in fact strings. Dates are represented in ISO-8601 format. 10am March 7, 2010 is represented as “20100307T100000”. If we ignore any time zone prefix, then the ical parser can discard events that are LESS THAN “20100306” without even having to perform any kind of calculation. Similarly if I only want to look ahead 14 days, I can similarly discard events whose date is GREATER THAN “20100321”. (The observant among you will have noticed that I have allowed an extra one day window either side of the start and end date filters to avoid missing dates because of time zone differences).

The second optimisation is based on the fact that for 10 out of 12 months of the year, the offset for a time zone is really easy to calculate. Using our example above, the GMT time zone offset (in hours) for Nov, Dec, Jan and Feb is 0. The daylight savings offset for Apr, May, Jun, Jul, Aug and Sep is +1 hour. Offset calculations to convert to UTC for any date among those 10 months is simple – the month is given by extracting characters 5 and 6 from the ISO date string.

Date times that occur in Oct or Mar require a more complex calculation to identify exactly which period of the time zone they sit in. This means that on average only 1/6 of all events require an expensive time zone calculation to convert the date/time to UTC.

You can see how these two simple optimisations can significantly reduce the amount of calculations that you need to make to process an ical file. And how a complex library like Joda Time isn’t really necessary to be able to process an ical file PROVIDED the file includes all the VTIMEZONE entries referenced by the VEVENT entries.

Written by airinformation

March 7, 2010 at 12:00 pm

Posted in development, ical

Tagged with , , , , , ,

Android Calendar Widget Released

leave a comment »

As a result of some people asking, I have released the Android calendar widget I created to replace the one supplied with my HTC Hero.

The screengrab shows both the HTC widget (top) and my replacement widget (bottom).

The HTC calendar only show the next event while mine will display up to 3 events (if they all occur the same day). As events pass, the widget will update (every half hour) to show the next three from the current time.

Note that the HTC (top) widget has a bug with all day events that causes it to display the event one day early. This screengrab was taken on Saturday 27 February but the HTC widget incorrectly lists the all day event on Monday 1 March as “Tomorrow” when in fact it should list “Monday 1 March”.

I’m making my alternative calendar widget available free of charge.

I don’t have any plans to add it to the Android Marketplace, so if you want it, please visit my Android Calendar Widget page and download it from there.

I hope you find it useful if you decide to install it.

Written by airinformation

February 27, 2010 at 1:16 pm

Posted in Android, development

Tagged with , ,

Android iCal parser

with 6 comments

Testing on the parser is going well as you can see by the screenshot to the left. Although the app currently exists only as a test harness it will be used to test each component and aspect of the iCal sync service.

You can see that the iCal information is coming from a Zimbra Collaboration Server. The ics datastream includes events defined in three timezones (with two seemingly similar ones). It also contains 94 events; some of which date back to 2007 in this particular calendar.

The eventual sync app will be designed to filter out events that don’t feature within a current time window (maybe today + 7/14/30 days). Why a time window? Well, I have a feeling that this may be required in order to reduce the amount of work that the app has to perform each sync – if you can discard redundant events without having to process them that has to be good, no?

As far as I can work out, the steps to get to a working ical sync app or background service are:

  • get the ics (iCal) file from a remote server
  • support self-signed certificates
  • handle timezone conversions for event entries (see below)
  • write events from the ics file into the Android calendar
  • develop a synchronisation algorithm between the ics source and the internal calendar
  • provide a configuration activity to create, edit and remove calendars
  • support different schedules and modes for synchronization
  • deal with recurring events
  • … and whatever else I haven’t yet foreseen!

I’m currently working on converting event date/times between timezones and UTC. iCal event entries are (normally) stored in their local timezone whereas Android calendar entries appear to be stored in UTC (universal coordinated time).

Written by airinformation

February 21, 2010 at 9:05 pm

Posted in Android, development

Tagged with , , , ,