IDisposable Thoughts... in asp.net :P

My blog in asp.net community

Handling TimeZone Information In ASP.NET

A few weeks ago on of my clients asked me to add international support for one of his web applications. Their current customers were located in different countries with different time zones. At first sight, it looks like an easy task, after all, .net has great support for globalization.

As expected, add internationalization and localization was an easy task to do, but after a few minutes of hacking I just realized it will not be an easy task to add multiple time zone support in a web application, the reason? simple: There is not an easy way in the server to get the client’s time zone location from the browser request. Yes, you can get things like .Net Framework installed, or even preferred browser languages, but no, there is no time zone information.

I googled for some hint to guide me in my journey, and the only thing I got was the obvious: Ask to the user where is his time zone preference and store it in user profile (database, or any other storage as you wish). Obviously my client didn’t want it, what they want is automatically detect client’s time zone location (in a future release probably they will add preferred client’s time zone modification in their application, but not in this release).

So I started looking for another way to bypass the issue. I remembered some old article in an ASP.NET Pro Magazine (now defunct), it was published at January 2007 and was entitled “It’s about Time” by someone named Alek Davis (sorry, no blog url found). Great article about how handle multiple time zones for the same web application. Sadly there was no sample source code available.

The solution background is simple:

  • Store every date as UTC date, you can use the method DateTime.ToUniversalTime from the .Net Framework
  • When display, Get the Browser Client’s Time Zone from somewhere
  • When display, Add client’s time zone hours to stored UTC time

There is just a little issue, how to get the client’s time zone information from the server?

Well, the article give us a light, there is a javascript function which returns browser’s time zone offset in minutes, such function is Date.getTimezoneOffset(), but now there is another issue, how to get that information back to the server? What about this:

  • Use javascript to get the time zone offset
  • Store that information in a browser cookie
  • Get that cookie with the client’s request
  • Get time zone offset value from the cookie

So, I decided to write a simple Http Module to intercept ASP.NET request, check if that cookie exists, otherwise, inject a simple javascript code which get time zone offset, create that cookie and refresh the page to the original request. Well, you can check the sample code :)

To use it, first add a reference to the library to your web project and configure your asp.net module in your web.config file:

<!-- for IIS6 -->
<system.web>
    <!-- more configuration over here -->
    <httpModules>
        <add name="ScriptModule" 
            type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="UtcModule" 
	    type="Cprieto.Utils.UtcInfoModule, Cprieto.Util.UtcInfo" />
    </httpModules>
</system.web>

<!-- for IIS7 -->
<system.webServer>
    <modules>
        <remove name="ScriptModule"/>
        <remove name="UtcModule"/>
        <add name="ScriptModule" preCondition="managedHandler"
            type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="UtcModule" preCondition="managedHandler"
            type="Cprieto.Utils.UtcInfoModule, Cprieto.Util.UtcInfo"/>
    </modules>
<!-- more configuration here -->
</system.webServer>

Now you can use the page extension with your project:

using Cprieto.Utils;

public partial class _Default : System.Web.UI.Page {
    protected void Page_Load(object sender, EventArgs e) {
        var current = DateTime.Now;
        var utc = current.ToUniversalTime();
        currentTimeLabel.Text = current.ToString();
        currentUtcTimeLabel.Text = utc.ToString();
        currentTimeOffsetLabel.Text = this.UtcOffset().ToString();
        calculatedTimeLabel.Text = this.LocalTimeFromTimeOffset(utc).ToString();
    }
}

There is an example web project in the source code if you want to check it.

Probably I will start to improve the current solution library. You could download my current source code from github http://github.com/cprieto/TimeZoneForAspNet

Note: Cross posted from IDisposable Thoughts.
Permalink

Comments

Abaid-ur-Rehman Zulfi said:

Dear Friend,

Can you please provide the source code in zip file as I was unable to get it from github.

Thanks in Advance.

# January 31, 2010 10:54 AM

VBCider said:

Thx for sharing - I was looking into the exact same issue - I was aware of the javascript timezone offset and was looking for a way to put it to use.

Your post have saved me some hours of work.

Thx agnin

# July 16, 2011 6:41 AM

MJ Ferdous said:

You can get the client TimeZone info from HttpContext

DateTime dtLocal = (HttpContext.Current.Request.RequestContext.HttpContext).Timestamp;

DateTime dtUTC = dtLocal.ToUniversalTime();

Then you can find UTC or difference with UTC

# July 20, 2011 6:19 AM

Jonathan said:

@MJ Ferdous, your solution only gives the UTC time on the server, not from the client machine. If you use Reflector and see how the Timestamp method is getting its value, you will see that this does not from from the client at all.

# August 2, 2011 5:29 PM