Time Zones

In a world of regular binary systems mapped on to an equally regular decimal counting system, the way we describe Time is like the ‘crazy’ outsider refusing to accept that the world has moved on.

60 seconds; 60 minutes; 24 hours; 28, 30 or 31 days; 365 and a bit days. Time Zones that are as much political as geographically sensible. Then throw in Daylight Saving and you have a recipe for complete confusion.

Here at Cronofy we have chosen to embrace dealing with time and handle as many of the complexities as we can on behalf of our customers. However our customers can’t ignore time when it comes to interacting with user’s calendars. So part of our role is to provide guidance and documenting how to achieve reliable behaviour.

At one side you have your application. This is usually describing times to the user in their local time zone.

Next you have the Cronofy API handling all of the interactions, synchronization and privacy for your application with all of the calendar servers.

Then you have the Calendar Server (Google, Exchange, Apple, Office 365, etc). Whilst there is generally not much interpretation that happens apart from filtering, they each have certain constraints as to how they’ll accept time being represented.

On the other side you have the Calendar Client (Outlook, Apple Calendar, etc) that the user actually interacts with. This will convert the time stored in the Calendar Server and/or position the event into the user’s local time zone.

Time Zones, Offsets and Daylight Saving #

Time Zones are a method of localising times such that 9am can have a common meaning across a geographical area. A meaning that relates more closely to the cadence of sunrise, sunset, the working day, local customs, etc. These are identified in the IANA Time Zone Database, mostly, with a Region/City descriptor.

eg: Europe/London, Australia/Sydney, America/Sao Paulo, Asia/Singapore.

There are other ways to describe them but the IANA descriptors are the most widely used and what we’ve standardized on here at Cronofy.

Another description you may see is Offset from Greenwich Mean Time (GMT). New York would generally be descibed as GMT-05:00. From a straight math point of view this sounds appealing however daylight saving means that the offset isn’t always consistent. Beware of using this as a means of calculating time in your application.

Daylight saving is generally implemented as a move forward or back of local time, relative to GMT. So New York can either be offset by 5 or 4 hours from GMT depending on the time of year. If the UK and the US switched to daylight saving at the same time (they don’t) then the local to local time offset would remain the same. However offsets are described against GMT which doesn’t change as a reference so the number of hours you need to add does change. This can be especially challenging when you’re dealing with future dates.

There is a 3 or 4 letter acronym that is generally used to indicate which time zone is being used and whether daylight saving is in place.

In the UK, GMT is used for non daylight saving periods, BST (British Summer Time) is used for times during daylight saving.

In Europe you have CET (Central European Time) and CEST (Central European Summer Time). On the east coast of the US you have EST (Eastern Standard Time, often abbreviated to just Eastern) and EDT (Eastern Daylight Time).

The Region/City descriptors described above also serve as lookups for the current application of daylight saving. The transition times do change, sometimes from year to year, depending on decisions made by local governments. The IANA Database coordinates these changes to ensure systems are up to date. Cronofy keeps our IANA Databse very up to date :).

Universal Coordinated Time (UTC) #

To allow times to be compared, UTC is a common time representation that dispenses with time zones. It happens that this coincides with GMT. There is also a common representtion format, ISO8601.

Midday in London on the 9th November corresponds to 2016-11-09T12:00:00Z. Whereas midday in London on 9th August, when daylight saving does apply in the UK, corresponds to 2016-08-09T11:00:00Z.

In New York on the same day in November, midday corresponds to 2016-11-09T17:00:00Z and in August 2016-08-09T16:00:00Z as the US also observes daylight saving.

In Singapore however, where daylight saving is not used, midday on 9th November is 2016-11-09T04:00:00Z and is at the same UTC time in August 2016-08-09T04:00:00Z.

You’ll note the Z suffix at the end of the time values. This indicates that the time is UTC.

How Cronofy Handles Time #

There are two types of interaction that involve time, querying and creating/updating events.

Querying #

Queries for data like events and free-busy slots are conducted using the data parameters from and to on the Cronofy API. These dates are considered ‘exlusive end’, ie the results returned will be up to but not including the value of to. There is an additional parameter tzid that is used to control how the from and to parameters are interpreted.

If Etc/UTC is passed as the tzid parameter then the query is conducted using midnight to midnight UTC eg:

from of 2016-11-09 and a to of 2016-11-17 would result in a list of records from 2016-11-09T00:00:00Z and before 2016-11-17T00:00:00Z.

If America/New York is passed as the tzid parameter then the query is conducted using midnight to midnight New York time eg:

from of 2016-11-09 and a to of 2016-11-17 would result in a list of records from 2016-11-09T05:00:00Z and before 2016-11-17T05:00:00Z.

This ensures that you can specify the local day boundaries to meet your applications purposes.

Creating and Updating Calendar Events #

Cronofy has standardized on UTC representation of times for describing event times. So all event times must be first converted to UTC before being submitted to our API.

{
    "start" : "2016-11-09T09:00:00Z",
    "end" : "2016-11-09:10:00:00Z"
}

In order to provide localization information to the Calendar Client we also support a tzid attribute on events. So whilst the the UTC version of the time may be confusing to a user, adding time zone information allows the Calendar Client to correctly localize it.

For example a one hour event at 6pm Los Angeles time on 15th November would be represented as:

{
    "start" : "2016-11-16T02:00:00Z",
    "end" : "2016-11-16T03:00:00Z",
    "tzid" : "America/Los Angeles",
}

Excluding the tzid would still mean that the event was rendered at the correct position in the user’s calendar. However when they opened the event, it is likely that they would see the time as 2am the following day.

It is also possible to specify a different tzid value for both start and end times. Useful when describing flights for instance. More information in our API documentation.

Translating Between Local Time and UTC #

We’ve tried to collate some useful examples in different coding languagues.

Rails #

zone = ActiveSupport::Time Zone['America/Los Angeles']
start = zone.local(2016,11,15,18,0,0)    # => Tue, 15 Nov 2016 18:00:00 PST -08:00
start.utc                                # => 2016-11-16 02:00:00 UTC
start.utc.iso8601                        # => "2016-11-16T02:00:00Z"

PHP #

$timezone = new DateTimeZone("America/Los_Angeles");
$date = new DateTime("2016-11-15 18:00:00", $timezone);
$date->format("r");
// => Tue, 15 Nov 2016 18:00:00 -0800

$date->setTimezone(new DateTimeZone("UTC"));
$date->format("r");
// => Wed, 16 Nov 2016 02:00:00 +0000

$date->format(DateTime::ISO8601);
// => 2016-11-16T02:00:00+0000

C# #

TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("America//Los_Angeles");
DateTimeOffset localTime = new DateTimeOffset(new DateTime(2016, 11, 15, 18, 0, 0), easternZone.BaseUtcOffset);
/* Tue, 15 Nov 2016 18:00:00 PST -08:00 */

DateTimeOffset utcTime = localTime.ToUniversalTime();
/* 2016 - 11 - 16 02:00:00 UTC */

We hope you’ve found this guide useful. Please email support@cronofy.com if anything isn’t clear or you have any suggestions for amendments or additions.