Today is the day Marty McFly from the movie “Back to the future” arrives in the future. He arrives on the 21.10.2015 at exactly 04:29pm.
Since I know the exact arrival time I planned to post a tweet to welcome Marty McFly. To find out how long I have wait I used this website http://www.backtothefuturecounter.com. The only problem was that this website gives you different times depending on your location. The page doesn’t account for the different time zones.
Site opened from Switzerland
Site opened from Hawaii
So let’s find the correct time. 04:29pm is probably the local time somewhere in the U.S. After some research I found out that the place Marty arrived in the future is Hill Valley, a fictional town in California. So the time zone is PDT, Pacific Time Zone UTC -07:00.
When Marty arrives in California at 21.10.2015 16:20 PDT it is going to be 22.10.2015 01:20 CEST here in Switzerland.
How to handle datetimes in your application
Handling datetime often brings complexity to a project. Errors caused by different time zones are hard to discover during development time. Here is a list of lessons learned during development of an application used worldwide.
Store and return UTC
UTC is the worldwide time standard. All time zones are expressed using positive or negative offsets of UTC. At the moment Switzerland has an offset of UTC+2.
Marty McFly arrives on 21.10.2015 23:21 UTC. By saving this date we can than easily convert the date into the local time of the user. For example +2h for Switzerland local time.
The format used in this example is ISO 8601 which is a standard to express date and datetime. It’s widely used in all popular libraries and Frameworks.
Use UTC as long as possible
Your application doesn’t need time zones – only users do.
Convert UTC to local time the moment you display the datetime to the user and convert user input (e.g. datepickers) back to UTC as fast as possible.
Sidenote: The REST API should be able to handle any ISO8601 datetime format, not just UTC. Especially if the API is public.
Make it clear in which time zone the date is
The tv schedule for the national tv station in Switzerland shows all times in local time. Everyone expects that. There is no need to add a time zone information here.
On the other hand it is necessary to have the time zone information for the moment Neil Armstrong made the first step on the moon.
Apollo 11 was the spaceflight that landed the first humans on the Moon, Americans Neil Armstrong and Buzz Aldrin, on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface six hours later on July 21 at 02:56 UTC.
CNN displays the time zone which is good for the global audience.
Don’t work directly with offsets
If you have to convert a UTC datetime
to local time in Switzerland programmatically you would have to evaluate whether the datetime is in the daylight saving time or not and then add one or two hours.
That sounds not too hard for Switzerland. But could you tell me
whether Hawaii has a daylight saving time?
when the daylight saving time was in 1960?
in which time zone Berlin was after WWII?
You would need this information for every country and for every given date. Luckily you don’t have to maintain this data by yourself. You can use the tz database – which brings us to the next point:
If you have to convert different time zones you need a database
There is no algorithm to convert time zones simply because there is no logic behind time zones.
Some countries have daylight saving time, some don’t and some countries like Samoa even changed their time zone completly.
The tz database is a collection of rules and gets updated several times per year. For example:
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Swiss 1941 1942 - May Mon>=1 1:00 1:00 S Rule Swiss 1941 1942 - Oct Mon>=1 2:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment. 0:29:46 - BMT 1894 Jun # Bern Mean Time 1:00 Swiss CE%sT 1981 1:00 EU CE%sT
Libraries using the tz database can convert a UTC datetime + IANA code into a local datetime. Here is an example with the excelent moment.js library:
var marty = moment("2015-10-21T23:21:00Z"); marty.tz('Europe/Zurich').format() // 2015-10-22T01:21:00+02:00
The nice thing with using the tz database is that you just define the region like ‘Europe/Zurich’. We never have to think about offsets.
Browsers don’t know time zones
http://www.backtothefuturecounter.com/ calculates the countdown with the users local time which is different for each user. Use moment.js if you need to convert to different time zones in the browser.
new Date('2015-10-21T23:21:00Z') // Thu Oct 22 2015 01:21:00 GMT+0200 (W. Europe Daylight Time)
Don’t misuse datetime for simple dates
You are born at a specific moment in history. But your birthdate is always local time from the place you’re born. You don’t change your birthdate when you move to Hawaii.
The best way to make sure that a birthdate is never converted to a different time zone is by keeping the date a date. There are great libraries for languages which don’t support date type nativly. For example http://nodatime.org/ for .NET.
There are always exceptions to the rule
There are cases where you never need to convert a datetime. Showtimes of a theater for example only make sense in the local time of the theater. To work with UTC datetimes would just bring more complexity to the application.
As a rule of thumb: The bigger an event the more likely you need to work with UTC.
Happy “Back to the future”-Day
Have a nice “Back to the future”-Day. And don’t forget: Changing time zones is not a time travel. It is always the exact same moment in history.