Users and web application in different time zones – challenges and possible solution with Javascript
Time zones… Where do we begin? It is a constant headache for developers and some developers just ignore it. I try always to force everything to UTC and only display the local time when needed in the UI. That gives me some sense of safety and control. These days I try to work with time zones in Javascript. And that gives me a set of new challenges since the computer owns the Date object in the browser and not the application.
The problem
Currently, I work with an Angular.js application for a client. This is my time challenge:
The USER can be in any time zone. The user of my application is mostly in time zone +01:00
(Norway) but can also be in +08:00
or -06:00
depending on where the user travels. The user works globally but edits information for the audience always in the Norwegian time zone.
The application is running in time zone +01:00
or +02:00
depending on the light saving or not, and if we push to Azure who knows? That depends on the data center.
The database stores everything in UTC to be sure we know what we have.
Creating a web application gives us some challenges, especially if the application is a single page application built on Javascript. The Javascript Date object always have the computer time zone. That means if you are in Samoa in the Pacific Ocean, then every Date object is in Samoa time zone.
So when I fetch a JSON date string from my server in Norway as UTC:
2015-02-01T17:20:00:000Z
it converts to a Date object that is on the morning the next day in Samoa:
2015-02-02T07:20:00:000+13:00
for the user in Samoa.
Ok, how is that wrong for this application? The date conversion is correct, but there is no way for me to say to my Angular.js application running in the browser.
“Hey, I want to see every Date object in the application as I was in Norway with my computer and not in Samoa”.
This simply cannot be done as far as I know, and I now have to start my string manipulation tweaking.
The workaround
So, I have my date string that I just fetched through my HTTP request:
2015-02-01T17:20:00:000Z
I pass in my date string in UTC and this string gets converted to a moment object. Then I can force the time zone conversion I want on that moment object using .tz
function and time zone identifier Europe/Oslo
. The time is now converted to Oslo time with +01:00
or +02:00
depending in daylight saving or not.
Can we use it then? No, because it is still a string or a moment object, and Angular.js wants it as a Javascript Date object.
So, the last step is to rip the time zone off the date time string after it is converted. We run the .format
function with JSON format style. YYYY-MM-DDTHH:mm:ss
. The output of this is:
2015-02-01T18:20:00
The final step is to pass this converted Norwegian date string to a moment function and then convert that to be a javascript Date object that can be used throughout the app and in all Angular.js controllers.
What happened to the date then:
We started with this in UTC:
2015-02-01T17:20:00:000Z
And get this date object with Norwegian time and Samoa time zone:
2015-02-01T18:20:00:000+13:00
So, using this approach do not care about the +13:00
behind the date. Everything I care about is the actual time and date. I force the date to be converted to the correct time zone from UTC and put on the local time zone at the end. This is comparable to the concatenation of time and time zone, not conversion. Using this approach, I can have a global time in the application that knows the current Norway time to compare the dates if needed. And converting back to DB I do the same. I rip off the time zone and force the date conversion from Norway time to UTC using moment objects.
Conclusion
This all seems a bit messy and it is. However, I have not been able to come up with a cleaner solution to force my web application to stay in Oslo, Norway at all times. I have gathered everything that calculate, convert and compare times in a centralized service in my Angular.js app. So when I do something with time, I call the same functions and have control that everything is local Oslo, Norway converted to and from UTC with the appended local browser time zone that I then can ignore. It works. The app runs like I was in Oslo, Norway in Samoa.
I know there are good initiatives out there to try to ease the time zone pain. To mention some libraries:
Do have an alternative approach to this or a simply a better way? Please share.