IDisposable Thoughts

Honey… where is my coding t-shirt?

Hey there! Thanks for dropping by Theme Preview! Take a look around
and grab the RSS feed to stay updated. See you around!

Posts Tagged ‘globalization’

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

Calculando la fecha UTC en SQL Server

Hace unos días me topé con algo interesante, cambiar la fecha ya establecida en los campos de una tabla a una estandarizada para varios paises. La solución simple fue utilizar la fecha UTC (GMT 0), pero ya en SQL Server las fechas estaban registradas con la hora local.

En SQL Server podemos obtener el tiempo actual UTC con la función GETUTCDATE(), utilizando esto a nuestro favor decidí crear un simple UDF para cambiar las fechas.

CREATE FUNCTION [dbo].[ConvertToUtc](@start datetime)
RETURNS DATETIME
AS
BEGIN
    DECLARE @offset INTEGER
    SET @offset = DATEDIFF(HOUR, GETUTCDATE(), GETDATE())
    RETURN DATEADD(HOUR, @offset, @start)
END

Luego el proceso es simple, como ejemplo, transformando la fecha actual a UTC:

SELECT ConvertToUtc(CURRENT_TIMESTAMP)

Problema de Culturas en la .Net Framework

Hoy es de esos dias cuando uno se topa con cosas que solo le queda decir “w00t”… Pasé durante un buen tiempo peleando con un formato de fecha en un asp.net website. Como algunos sabran ya de antemano, una forma de obligar al website de asp.net a comportarse de una manera específica es agregando esto al web.config:

<system.web>
    <globalization culture="es-PA" />
</system.web>

El parámetro de culture debe ser una “full qualified culture name” o sea, no sólo el idioma sino el carácter regional (en este caso en específico español-Panamá, mi país de origen). Debido a que el proyecto que estoy trabajando es específicamente para ese país, no consideré ningun problema al agregarle la especificidad de cultura.

Luego de revisar todo, me doy cuenta que el formato de fecha corta no se presenta como es de esperar, yo esperaba dd/mm/yyyy y obtenía mm/dd/yyyyy (como el formato de fecha anglosajona). Al revisar las opciones regionales de mi sistema operativo (y de varias máquinas alrededor) me doy cuenta que la Framework correctamente esta proyectando la regionalización para es-PA, eso implica dos cosas:

  • O viví y crecí en Panamá durante más de 19 años y JAMAS los panameños escribimos bien la fecha
  • O Windows XP en adelante, alguien en Microsoft decidió que Panamá tendría un formato de fecha diferente al que los panameños acostumbramos a usar.

Los dolores de cabeza con que uno se topa verdad?