2012-01-03 17 views
7

Tengo una aplicación ASP.NET y una marca de hora UTC en el servidor. Deseo mostrar la marca de tiempo al usuario en la zona horaria correcta y usando el formato de fecha/hora local.Cómo mostrar información de fecha y hora localizada a usuarios de la web con ASP.NET

E.g. Jan 2, 2012 14:00:00 UTC debe mostrarse como 1/2/2012 9:00 AM a un usuario en Nueva York, Estados Unidos (UTC -0500) y como 02/01/2012 14:00 a un usuario en Londres, Reino Unido.

Esta tarea aparentemente simple demostró ser sorprendentemente difícil. MSDN has an article con el mismo título, pero se trata de analizar la entrada del usuario en lugar de mostrar los datos del lado del servidor, por lo que no se aplica por completo.

La zona horaria se determina fácilmente en el cliente a través de JavaScript

offset = new Date().getTimezoneOffset();,

pero JavaScript ofrece muy poco apoyo para el formato de fecha/hora. Todo lo que obtienes es toLocaleString() método, lo que resulta en cadena larga fea como Monday, January 02, 2012 9:00:00 AM. No hay ninguna disposición para formatos más cortos, por lo que en el cliente estamos atrapados con buena información de zona horaria y malas capacidades de formato de fecha/hora.

La situación es exactamente opuesta en el servidor. Podemos aprovechar la cabecera HTTP Accept-Language para obtener la configuración regional del usuario (not the best choice, but may be good enough), y luego puntee en la base de datos .NET de los lugares conocidos, por lo que nuestro código va en la línea de

CultureInfo userCulture = new CultureInfo(Request.UserLanguages[0]); más algo de manejo de errores.

Pero luego estamos atascados en el problema de la zona horaria. Sí, uno puede obtenerlo a través de JavaScript y luego devolverlo como una cookie o como datos de devolución de datos, pero ¿qué sucede si tenemos que mostrar las fechas en la primera página de la aplicación? Se puede argumentar que la primera página siempre es la página de inicio de sesión, pero no es así cuando la información de inicio de sesión del usuario persiste entre sesiones (opción "recordarme"). La solución podría ser ahorrar el desplazamiento de la zona horaria como parte del perfil del usuario, pero luego puede volverse obsoleto (entrar y salir del horario de verano entre las sesiones).

¿Existe una solución integral a este problema que funciona bien y no requiere escribir toneladas de código? Tengo mucha curiosidad, por favor asesora.

Respuesta

4

debe pasar la cadena de tiempo al cliente en un formulario estándar, tales como ISO8601:

var timeString = '2012-01-02T16:00:00Z'; 

algunos navegadores analizar correctamente las cadenas de ISO8601 y algunos de costumbre, por lo que analizar de forma manual para estar seguro. Eso es bastante simple: crear un objeto Date local, entonces ajustar la fecha y la hora UTC:

function localDateFromUTC(s) { 

    var x = s.split(/[-\s:tz]/i); 
    var d = new Date(); 

    d.setUTCFullYear(x[0], x[1], x[2]); 
    d.setUTCHours(x[3], x[4], x[5]); 
    return d; 
} 

var s = '2012-01-02T16:00:00Z'; 
var d = localDateFromUTC(s); 
alert(d); // Shows local date and time for the provided UTC date and time 

Si desea una salida específica, es necesario formatear manualmente, por ejemplo,

function formatDate(d) { 
    var days = ['Sunday','Monday','Tuesday','Wednesday', 
       'Thursday','Friday','Saturday']; 
    var months = ['January','February','March','April','May','June','July', 
       'August','September','October','November','December']; 

    return days[d.getDay()] + ', ' + d.getDate() + ' ' + 
       months[d.getMonth()] + ', ' + d.getFullYear(); 
} 

puede probar a usar toLocaleString() pero los resultados varían enormemente entre los navegadores, la mayoría parece ignorar la configuración local de todos modos.

+0

_Si desea una salida específica_ Me gusta la idea de pasar una fecha como esta, pero el problema de determinar el formato de fecha/hora local permanece sin resolver.¿Cómo sabes qué usar: '' 01/02/2012 2:00 PM '', '' 2012-01-02 14.00 '', o, quizás ''02 .01.2012 14: 00''? –

+0

La solución habitual es escribirlo en un formato inequívoco, como "2 de febrero de 2012", que cualquier persona debe entender claramente, incluso si prefieren sus fechas en algún otro formato. Si los navegadores tenían un * toLocaleString * decente, podría usarlo, pero no es así. – RobG

+1

Traté de realizar una ingeniería inversa de cómo gmail maneja las zonas horarias. Es bastante inteligente de hecho. Sin embargo, fechan el formato y la zona horaria de conversión en el servidor. En el cliente, intentan determinar las fechas de los interruptores de ahorro de luz diurna (si corresponde) realizando búsquedas binarias entre el 1 de enero de 2010 y el 30 de junio de 2010 y luego el 30 de junio y el 1 de enero de 2011. Codifican esa información, junto con la hora actual offset de zona, en una cadena y (¡cuidado con mis manos!) do '(new Image) .src = codded_string'! De esta forma, pueden pasar los datos al servidor antes de que la página principal termine de renderizarse, sin cookies O postback. –

Cuestiones relacionadas