Home > General Programming > Proper Localization of Dates and Times

Proper Localization of Dates and Times

Overview

The localization is one of the most important aspects of every software product. It doesn’t matter if it’ll be used in different languages, it will quite certainly be used in different timezones. The risk of shipping a product with no (or limited) i18n support is neglectful only in case your targeted customer base is located in a specific geographical location and you are absolutely certain it will not pose a problem. Nonetheless, if you decide to expand your business in the future, be 100% sure that at some point you’ll need to take care of this.  

Unfortunately, the bigger part of the developers, technical leads and managers are simply not aware of the specific problems. As a consequence of that, 2/3 of the software products worldwide will not provide the correct time under certain circumstances. 

Let’s define the problems, both general and concrete, and think of appropriate resolutions.  


Taking the time into consideration

At first sight, there is nothing very special about holding the user’s time. Let’s say we have a 3-tier web application and a bunch of users using the system. There are various forms, some of which have time fields and most of the actions need a timestamp. 


Defining the problem

The different times are processed by a server and placed in a persistent storage. But what time exactly will you store on the backend ? Is your server in the same timezone as your storage ?

localization-timezones

The problem with storing the time as it is put from the user is that the user might be located in a different timezone. If you directly store the input, you’ll have a localized time in a specific timezone. If someone from a different part on the globe decide to extract that time, how could he figure the exact time zone so he can adjust the appropriate offset ?

He will not be able to. 

 

Thinking of resolutions

The first thing that comes to mind is to store the user’s offset, along with the time, in the persistence storage (let’s say a database). Although it’s a possible solution, it’s not the smartest one. You’ll need an additional column for that and it feels dirty. 

A better approach would be to use the Coordinated Universtal Time format. 
 

Storing the time in UTC format 

The best practice is to store the time in the Coordinated Universal Time (UTC) format. All the timezones around the globe are represented by an offset from this time, meaning that having the user’s offset for every request can help us easily convert the UTC in the correct timezone. 
 

Ways of obtaining the timezone information from the client

So far so good. But how exactly would you extract the timezone information from the client’s browser ? Through the HTTP headers ? 

Nope, you’ll not find such information there. 
 

Using Date.getTimezoneOffset() to acquire the offset

A more realistic solution would be to use JavaScript’s Date.getTimezoneOffset() method. It’s a simple method from the standard JS library that would allow us to obtain the timezone offset. At first sight, it feels like the best solution. We send the offset to the server, convert the time to UTC and store it in the database. For every consequent call for any of the timings, we use the same method to get the offset and produce a proper time for the client at hand. 

And that will work properly most of the time. However, if you want to create a robust software, “most of the time” just doesn’t sound right. Which brings us to the reason behind that. 
 

The Daylight Time Savings (DTS)

Simply using the offset to convert from and to UTC will not work due to the Daylight Time Savings (DTS) settings used in most of the western nations. 

localization-daylight-savings-image

  DST is used.
  DST is no longer used.
  DST has never been used.
Source: Wikipedia
 

And guess what ? The Date.getTimezoneOffset() will just get you the offset, regardless the DTS. Meaning that you can’t depend on it for a precise metric.  

 

The possible solutions

I see three possible solutions to this problem. 
 

Solution #1

Ask the user to specify his timezone from a list of possible choices.

MSDN Timezone list

Whatever his choice is, store it in the database. Note that we don’t store the offset, we store the timezone which will allow us to utilize the default mechanism provided by most of the contemporary frameworks. When a request for a time comes, retrieve the timezome and use the appropriate methods on the time to convert it to the correct timezone. This will take the DTS settings under consideration. 

Example code from MSDN:

    DateTime easternTime = new DateTime(2007, 01, 02, 12, 16, 00);
 
    string easternZoneId = "Eastern Standard Time";
 
    try
    {
       TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
       Console.WriteLine("The date and time are {0} UTC.", 
                         TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone));
    }
    catch (TimeZoneNotFoundException)
    {
       Console.WriteLine("Unable to find the {0} zone in the registry.", 
                         easternZoneId);
    }                           
    catch (InvalidTimeZoneException)
    {
       Console.WriteLine("Registry data on the {0} zone has been corrupted.", 
                         easternZoneId);
    }

 

Solution #2

This is not the clearest solution, but I guess it’ll work. 

We got Date.getTimezoneOffset() method which will return the user’s offset with or without DTS. Isn’t there a flag which says if DTS is at hand ? Some method to tell us if a daylight time change is in place ?

There is not. 

But you can use a little hack, nicely packed within the prototype of the Date class in Javascript.

    Date.prototype.stdTimezoneOffset = function() {
        var jan = new Date(this.getFullYear(), 0, 1);
        var jul = new Date(this.getFullYear(), 6, 1);
        return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
    }
 
    Date.prototype.dst = function() {
        return this.getTimezoneOffset() < this.stdTimezoneOffset();
    }

It makes use of the assumption that if there are two dates, for the first of which we know that is without DTS and for the second that is with DTS, from the same timezone, we can use them for comparison to find out if our own time is with DTS or not. 

This could allow us to store a correct offset for the user in the database. Nevertheless, I'm not convinced that there are two dates for which we know for sure they meet the criteria. But it’s an automatic solution. Also, the fact that the browser (and therefore the JS engine) thinks that it knows the offset, doesn’t mean the user really wants that setting or even knows that the setting is there. 
 

Solution #3

Ask the user for his timezone in a droplist. Provide an auto selection “educated guess” based on the offset provided from Javascript. Once entered, keep checking the offset value behind the scenes for inconsistencies. If you detect some – ask the user to select a new timezone. 

Personally I think it’s the best approach, although not automatic it provides a coherent combination of manual precision and automatic selection. Whatever approach you decide is best for your case, make sure to configure the server’s time settings to UTC. Otherwise, you’ll run into hideous issues when using your framework’s time conversion methods. 

 


That’s all from me on this matter, hope this information will help you make the right decision. ;)

 



Like the article ? Share it ! ;)


  1. Andrew
    July 3rd, 2013 at 20:25 | #1

    Why not just use Javascript's Date().getTime() and transmit that to the server, then on the server it can create a Date object using the # of milliseconds since the epoch, which is timezone independent. Assuming that you have consistency for how the server-side and storage deal with dates, it should mean that your storage has been normalized to a single timezone (UTC, or something common).  When presenting dates on the client, you'll have to serialize the date as the # of milliseconds since the epoch, then apply formatting using the Javascript Date's getters (or use a library such as dojo) so that the date is presented according to the client's timezone.

    Ideally, the date is presented with the timezone abbreviation to the user so there's no question about the moment being represented, and optionally, (the JS Date API has getters specifically for this) display the formatted date per UTC too. 

  2. Jim
    July 4th, 2013 at 00:04 | #2

    I store the time as unix epoch for UTC.

     I just take the time as  unix epoch and multiply times 1000  and convert it with javascript in the browser.

  3. July 4th, 2013 at 20:47 | #3

    Andrew, Jim, 

    We can't simply get JavaScript's Date().getTime() and transmit it to the server. Given only the milliseconds, the server doesn't have any means to determine the correct timezone of the client nor if DTS is at hand. We could send the offset, but in that case there is also no way to determine if DTS is active. 

    The best way to check this is to leave this task to a system that knows how to calculate it. We have two such systems: the Operating System and the server-side framework, which usually have functions to convert a time with a given timezone ID from and to UTC. That's what we do in Solution #1 . In Solution #2, we use a little hack that might also do the trick, but I'm not sure it's the best choice from a usability point of view. 

    Regards, 
    Kosta

  1. No trackbacks yet.


Copyright © Developing the future 2013. Licensed under the CC> BY-NC-ND 3.0 Creative Commons license.       
Audi R8 wallpapers Sony Xperia Z4 Tablet WiFi