Browser (javascript) timezone to .NET timezone (DST problem) with fallback

Yet another timezone post. Did I mention that I don’t like timezones? I don’t understand why the browser cannot only give us a timezone identifier according to a standard, like IANA.

Anyway I identified a problem related to Daylight Saving Time (DST). I needed to create an Excel file (and some PDFs) on the server side as a response to a button click. I thought immediately on the problem, that I need to send the timezone offset minutes from the browser, so that I can present correct times for the person using the app. We store date values in UTC generally in our database.

“Luckily” I started with this task on a day which was in winter time and I finished the task on a day which was already in summer time. I created a report on Friday and on Monday and saw that the corrected time was different. Oh yeah, this means, that the time has to be adopted to “local time” not according to the current timezone offset, but according to the timezone offset at the time of the “local time” according to the browser’s timezone. The solution is easy – I thought – I just need to send the timezone information to the server instead of the offset. It turned out not to be so easy.

First I wanted to get a better understanding about the topic, so I started here: http://encosia.com/how-i-handle-json-dates-returned-by-aspnet-ajax/. I’ve found everywhere pretty ugly solutions for it, like this. I just couldn’t believe, that there is no better way.  

Then I’ve found a solution for the topic with the moment.js. It was pretty hard to figure out, how to create the moment-timezone-data.js file, till I’ve found it pressing the Data button on their site (http://momentjs.com/timezone/data/), and clicking together a “Browser” variant, and copied it into the above named js file. The problem was, that the solution didn’t work for the specific time zone I needed (in Australia). Sad, but this lead to the situation, that I’ve understood the problem really.

My solution was in the end the following:

  1. As a main solution
    1. Use HTML5 Geolocation API (navigator.geolocation) to get longitude and latitude information, described e.g.: over here.
    2. The longitude and latitude information can then be combined to determine the timezone as described here.
  2. As a fallback if the user doesn’t share his/her geolocation
    1. Added the javascript library jsTimezoneDetect (https://bitbucket.org/pellepim/jstimezonedetect)
    2. Sent the IANA timezone name calculated to the server
    3. Used the Noda Time library (available on NuGet: NodaTime) to convert it to windows time zone identifier as described here: http://stackoverflow.com/questions/17348807/how-to-translate-between-windows-and-iana-time-zones.

A much more precise way is to use the new HTML5 Geolocation API, however the user cannot be forced to allow us. The jsTimezoneDetect is quite OK as a fallback solution. It worked for me for the timezones I certainly needed.

I also know that Noda Time is a bit of an overkill, as one could also just use the the Unicode CLDR for the IANA to Windows identifier resolution, but I was now just too lazy :)

The longitude and latitude information can also be combined with the data gotten from online services as described here. I didn’t like this way at all, therefor applied the solution above.

Advertisements

About Tamas Nemeth

Husband and proud father of two daughters in Nürnberg. I'm working as a Senior Software Developer and an enthusiastic Clean-Coder. I spend most of my free time with my family (playing, hiking, etc...). I also play table-tennis and badminton sometimes...
This entry was posted in Technical Interest and tagged , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s