Developing web application with time zones support

When you develop web application you should know that client PCs can be located anywhere on earth. Even if you develop app just for your country users you should remember it (in Russia now we have 9 time zones, before 28 of March we had 11 time zones). On big sites with many members do it very easy – you can place field “time zone” in member profile, in Sharepoint I saw this solution, and many enterprise app do it like this. But if we have simple website with blog publications or website with news and we don’t have member profiles on server, how we can support user’s time zones?

I thought about this question because I wanted to develop time zone support on my own site. My case is ASP.NET MVC app and MS SQL Server DB. First, I started from learning which params we have at HTTP headers, but it doesn’t have information about it. So we can’t use regional settings and methods DateTime.ToLocalTime and DateTime.ToUniversalTime until we get user time zone on server. If we used our app before without time zones support we need to change dates from local time zone to UTC time zone (something like Greenwich Mean Time). You can do it easily with this sql update statements:

update dbo.MyTable set [Date] = dateadd(hour, -4, [Date])

I have -4 in this statement because time zone of server is GMT+4 (summer time). Next in code where you get current time you need to change functions: in tsql scripts getdate() to getutcdate(), and on server change DateTime.Now (or Today) on DateTime.Now.ToUniversalTime(). So on server (app and DB) we will always have dates in UTC time zone.

Next step – how to show datetime on client in browser. We need to show correct time for user (in his time zone). Get user time zone you can with Javascript function getTimezoneOffset(), it return difference in minutes from UTC to user time zone. On server I render all dates in format “dd.MM.yyyy HH:mm”. All dates I placed in html element with CSS class utcdate, if date located in text I just surround it with span element. So all dates I have like this:

<h3 class="utcdate"><%= Model.BlogPost.Date.ToString("dd.MM.yyyy HH:mm")%></h3>

And definition of CSS class utcdate:

.utcdate {display: none; }

When user get page all dates are invisible. I did it because on some pages in Internet Explorer we can see how old dates change with other dates (in other browsers JavaScript change it very quickly).

I wrote this JavaScript code for this:

function utcToLocal(u) {
    var l = new Date(u.substring(6, 10), u.substring(3, 5)-1, u.substring(0, 2), u.substring(11, 13), u.substring(14, 16));
    var d = new Date(l.getTime() + (-l.getTimezoneOffset() * 60 * 1000));
    return wZ(d.getDate()) + '.' + wZ(d.getMonth()+1) + '.' + d.getFullYear() + ' ' + wZ(d.getHours()) + ':' + wZ(d.getMinutes());
}
function wZ(x) { if (x <;= 9) return '0' + x; return x; }
function doCurrentDate() {
    $(".utcdate").each(function () {
        if ($(this).css("display") != "inline") {
            this.innerHTML = utcToLocal(this.innerHTML);
            $(this).css("display", "inline");
        }
    });
}
$(document).ready(function () {
    doCurrentDate();
});

I confess that I’m not a professional in JavaScript, so maybe you will say me how to do it better. I use jQuery, write this functions without jQuery will be more difficult, because jQuery help with selectors. Last 3 lines of this script on document ready state invoke doCurrentDate() function, which find all elements with css class utcdate and do for each: if display property of style doesn’t have ‘inline’ value than with function utcToLocal we change date from utc to user time zone and set ‘inline’ value for property display.

Function utcToLocal it is very simple. It parses input string on each date time parts, creates new date object, and then creates new date object from previous with adding required amount of time (getTime() return milliseconds, so we multiply value of getTimezoneOffset on 60 seconds in minute and 1000 milliseconds in second), and then It return formated value of date. I added function wZ, which add 0 before value if needed, because I want to show 01.01.2010 instead of 1.1.2010 on my site.

Because in method doCurrentDate we have check that date is changed on user’s time zone (check that display hasn’t ‘inline’ value), we can invoke this function so many times as we need. So when on my site user added comment (I use AJAX for add comments and include html of it with JavaScript at page) I can invoke doCurrentDate again.

Of course it is no good, that I don’t use user’s date format for showing date, because in US date format is MM/dd/yyyy and in Russia is dd.MM.yyyy. You can use JavaScript function toLocalString() which return formatted string with date. But it placed seconds and days of week, and I don’t want to see it on my site, I think that it is trash :)

I think will be great if HTML 5 format will have html date supports. Example, you can write this on page:

<date>03.04.2010T00:38:00+04:00</date>

And browser will change it in user’s local time. And date element can use some attribute for specify which date format you want to see on your site.

Shout it kick it on DotNetKicks.com

Comments (2)

Loga ( ) #
gravatar
Good article!
I'll use it in my project.
Хорошая статья.)
Denis Gladkikh ( ) #
gravatar
Loga, thanks. (This article have russian variant - http://outcoldman.com/ru/blog/show/197

:)
Submit Comment
If you want to get notifications about new comments at this topic, please fill email text box and check proper item. If you want to place source code in comment body place it in tags [code]...[/code], you can set language like this [code cs]...[/code], where cs can be cs, html, xml, java, js, php, sql, cpp, css.

 

busy