What every developer ought to know about timezones wrt calendar files

A timezone definition consists of

  • a ID
  • a name
  • a standard time definition with a gmt offset
  • daylight saving time definitions with a series of daylight saving transitions (as rules have changed over time

Ideally every system around the world should be using the same definition of timezones.  However not all systems are kept up to date when a government decides to change a transition time.  In addition not all systems use the same naming conventions, so while to the human it may be obvious which timezone is being referred to, a program has to do some deductions.

Most calendar applications appear to use the olson database or similar.  Windows PC take a slightly different approach, with a requested time change on the first reboot after daylight saving change.  Windows based application issue different timezone ID’s.

A calendar application can decide on it’s own timezone id’s. They have to include the definition (The VTIMEZONE) with the daylight saving changes in the file, however this can be their own version of the timezone definition

What if the issuing application has an outdated version of the daylight saving changes?  Would you not rather control it on your server than taking their definition?

Global Timezone Database

Php, WordPress, Google, Linux (Ubuntu), Apple

These all appear to use the timezone database aka Olson Database.  It has timezone identifiers like:

Australia/Sydney

Fbcal.com

A few months ago, Issued no TZID, no VTIMEZONE, all dates local / floating and just this : X-WR-TIMEZONE;VALUE=TEXT:Europe/Oslo

Mozilla sometimes has great fun confusing people:

DTSTART;TZID=/mozilla.org/20050126_1/America/Denver:20070101T090000

Artistdata.com

Recently I dealt with an ics file that had no TZID, no VTIMEZONE, all dates local / floating

Microsoft Windows PC, Microsoft Exchange

Setting TimeZone in Windows Vista

Microsoft exchange, Windows PC’s and by extension any application that runs on the PC that uses the windows timezones does the gmt offset thing

(GMT+10:00) Canberra, Melbourne, Sydney.

Now Sydney has daylight saving, so we are only GMT+10 for half the year.  The rest of the time we are GMT+11.  If we happen to choose the GMT+11 option for our setup thinking it was more correct we would be wrong…..

What windows does is technically not wrong.  They acknowledge the daylight saving and you can choose to have it automatically update… WHEN you REBOOT the PC, the times will update.

It is however potentially misleading, unnecessarily so.  Particularly around the actual daylight saving change, errors may occur, due

  • an ‘old’ ics file perhaps – the one issued before the times were updated ?, or
  • to applications not always handling the timezone  correctly – It would be very tempting as a programmer to grab that GMT+10 and use that.  Just google things like my meeting is one hour out etc to get a feeling for the problem.

What does this mean for developers using calendar files?

Well it depends a bit on the application issuing the ics file.  You could have to deal with any of these timezone values:

Examples:

  • TZID:America/New_York
  • DTSTART;TZID=”America/New_York”:20080807T090000
  • X-WR-TIMEZONE:Europe/London
  • TZID:Europe/London
  • DTSTART;TZID=Europe/London:20060707T130000
  • TZID:Canberra\, Melbourne\, Sydney
  • DTSTART;TZID=”Canberra, Melbourne, Sydney”:20100831T210000
  • X-WR-TIMEZONE;VALUE=TEXT:Europe/Oslo
  • DTSTART;TZID=”(GMT+01.00) Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna”:20100831T16000
  • TZID:(GMT+02.00) Harare/Pretoria
  • DTSTART;TZID=US/Central:20080726T190000
  • DTSTART;TZID=/mozilla.org/20050126_1/America/Cancun:20070101T090000
  • DTSTART;TZID=”(GMT) Greenwich Mean Time – Dublin / Edinburgh / Lisbon /
  • TZID:/mozilla.org/20050126_1/Pacific/Yap

Windows – assessed using Windows Calendar

Windows Calendar Ics file

Windows calendar defines the TZID with a VTIMEZONE definition

TZID:Canberra\, Melbourne\, Sydney
BEGIN:STANDARD
...
TZNAME:AUS Eastern Standard Time...

and then uses it in the ics file

DTSTART;TZID="Canberra, Melbourne, Sydney":20100831T210000

This is correct according to the spec and not too hard to deal with.    The developer can grab each city and check for a matching timezone on their host system.

A minor gripe is that if you import this into Google and then share the resulting google calendar file, Google will decide to go with Melbourne, even if the rest of your calendars are Sydney.  This may offend some. ;-)

Zimbra

I’m told that Zimbra issues ics files with :

DTSTART;TZID="(GMT+01.00) Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna":20100831T160000

I don’t know whether a VTIMEZONE was included or not.  AS noted before grabbing that GMT+01 may cause incorrect times when daylight saving is involved.

At the very least the reading application  has to deal with that somehow. Possibly by tossing the GMT parts away and looking for the cities again.  My events plugin will do this in the next upgrade

Mozilla / Thunderbird

Mozilla plays nicely (with php anyway!)

PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Australia/Sydney
...
DTSTART;TZID=Australia/Sydney:20100901T170000

Reading the VTIMEZONE definition?

Somehow working with the timezone definition passed in the ics file – Is this an option ? – well maybe – I shudder to think how though. Imagine the confusion if some dates in your website knew about one set of daylight saving and others were obeying the possibly different definition in the ics file. PHP encourages us to use it’s timezone definitions. It has functions to do a variety of timezone functions, but uploading daylight saving changes into a timezone object is not one of them. (Probably a good idea too).

Parsing Timezone Ids

If you are developing an ical parser, I believe that the best approach (wrt correctness and usability) is

  1. attempt to determine the desired timezone from the TZ id (toss those GMT’s if you have too)
  2. match to a timezone identifier that is already in your system, and then use those consistent daylight saving changes
  3. and of course use the DateTime object class – do not mess around with unix time that breaks on old dates.
    Dates, Times, Timezones, daylight saving etc are so fraught with danger (see the best of dates, the worst of dates), that one must use pre-tested logic as much as possible, and there are some very useful functions there.

My amr-ical-events-list plugin

For the record, my plugin will attempt to cope with all of these variations (and more if anyone tells me about them).   If we can extract some city names, it should be easy to match it at least one to the php timezones:

  • explode the names out, stripping off all the quotes, slashes etc
  • If a timezone has been specified in the shortcode, and it matches the city name, then it will deduce that is the timezone
  • If the wordpress timezone  matches the city name, then it will deduce that that is the timezone
  • Else if will attempt to find a match in the php timezone names list (which it should unless something really weird is going on)
  • Else if all that fails, it will just use the wordpress timezone as the base timezone for the events.

Extract From http://tools.ietf.org/html/rfc5545

This property parameter specifies a text value that uniquely identifies the “VTIMEZONE” calendar component to be used when evaluating the time portion of the property. The value of the “TZID” property parameter will be equal to the value of the “TZID” property for the matching time zone definition. An individual “VTIMEZONE” calendar component MUST be specified for each unique “TZID” parameter value specified in the iCalendar object.

Failure to include and follow VTIMEZONE definitions in iCalendar objects may lead to inconsistent understanding of the local time at any given location

The presence of the SOLIDUS character “/” as a prefix, indicates that this “TZID” represents a unique ID in a globally defined time zone registry (when such registry is defined).

Note: This document does not define a naming convention for time zone identifiers. Implementers may want to use the naming conventions defined in existing time zone specifications such as the public-domain TZ database [TZDB]. The specification of globally unique time zone identifiers is not addressed by this document and is left for future study.