Pregunta

Estoy trabajando en un " sistema de recordatorio en línea " proyecto (ASP.NET 2.0 (C #) / SQL Server 2005)

Como se trata de un servicio de recordatorio que enviará el correo a los usuarios en determinadas fechas. Pero el problema es que los usuarios no son de un país específico, son de todo el mundo y de diferentes zonas horarias. Ahora, cuando me registro, solicito la zona horaria de los usuarios de la misma manera que Windows pregunta nuestra zona horaria en el momento de la instalación.

Pero no entiendo si el usuario seleccionó (+5.30) o algo de zona horaria, entonces cómo manejar esta zona horaria en mi aplicación asp.net. Cómo trabajar según la zona horaria.

Y sugiera si hay alguna manera mejor de manejar zonas horarias en esta aplicación.

Gracias

¿Fue útil?

Solución

Lo primero es asegurarse de en qué zona horaria se encuentran sus datos. Recomiendo asegurarse de que cualquier DateTime que almacene esté almacenado en la hora UTC (use DateTime.ToUniversalTime () para agarrarlo).

Cuando vaya a almacenar un recordatorio para un usuario, necesitará la hora UTC actual, agregar o eliminar la diferencia de zona horaria del usuario y convertir esa nueva hora nuevamente a UTC; esto es lo que quieres almacenar en la base de datos.

Luego, cuando desee verificar los recordatorios para enviar, simplemente debe buscar en la base de datos los recordatorios para enviar ahora, de acuerdo con la hora UTC; esencialmente obtenga todos los recordatorios que tengan una marca de tiempo anterior a DateTime.Now.ToUniversalTime () .

Actualización con algunos detalles de implementación: Puede obtener una lista de zonas horarias del método TimeZoneInfo.GetSystemTimeZones () ; puede usarlos para mostrar una lista de zonas horarias para el usuario. Si almacena la propiedad Id de la zona horaria seleccionada, puede crear una instancia de clase TimeZoneInfo a partir de ella y calcular la hora UTC para un valor de fecha / hora local dado:

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("<the time zone id>");
// May 7, 08:04:00
DateTime userDateTime = new DateTime(2009, 5, 7, 8, 4, 0);
DateTime utcDateTime = userDateTime.Subtract(tzi.BaseUtcOffset);

Otros consejos

Recomendaría siempre usar la hora UTC (GMT) en el lado del servidor (en código subyacente, base de datos, etc.) y convertir la hora de UTC a hora local para fines de visualización solo. Esto significa que todas las manipulaciones de tiempo, incluido el ahorro de tiempo en la base de datos, la realización de cálculos, etc., deben realizarse con UTC.

El problema es: ¿cómo sabe su código subyacente cuál es la zona horaria del navegador del cliente? Digamos que el usuario ingresa algún valor de fecha / hora (como 30/12/2009 14:30 ) en el formulario y lo envía al servidor. Suponiendo que el usuario envió la hora local, ¿cómo sabe el servidor cómo convertir este valor a UTC?

La aplicación puede pedirle al usuario que especifique la zona horaria (y guardarla en una cookie o base de datos persistente), pero requiere un esfuerzo adicional por parte del usuario, y su aplicación necesitaría implementar la lógica y las pantallas para esto. Sería mejor si la aplicación pudiera determinar la zona horaria del cliente automáticamente .

He abordado este problema con la ayuda de la función getTimezoneOffset de JavaScript, que es la función solo API que puede informar al servidor sobre la diferencia horaria entre la hora local en el cliente y GMT. Como se trata de una API del lado del cliente, hice lo siguiente: en el lado del servidor, compruebe si hay una cookie de sesión personalizada que contenga el valor de compensación de tiempo y, si no está disponible, vuelva a cargar la página (solo durante las llamadas GET y no POST) con cierta lógica de JavaScript agregada para generar el desplazamiento de tiempo y guardarlo en la cookie. Desde el lado del cliente, esto es casi transparente (una vez durante la sesión vuelvo a cargar una página en GET). Una vez que tengo el desplazamiento en la cookie, lo aplico a las funciones de administración del tiempo dependiendo de la conversión de la dirección del tiempo (UTC a hora local, u hora local a UTC).

Esto puede sonar un poco complicado, y lo es, pero después de que escribí funciones auxiliares, integrar esta función en el sitio fue cuestión de hacer una llamada única en Page_Load (de páginas que necesitaban tiempo conversión), y el uso de rutinas de conversión de tiempo al enviar y recuperar valores de tiempo desde y hacia el navegador. Aquí hay un ejemplo de cómo se puede usar:

using My.Utilities.Web;
...

// Derive the form class from BaseForm instead of Page.
public class WebForm1: BaseForm
{
...
private void Page_Load(object sender, System.EventArgs e)
{
  // If we only want to load the page to generate the time
  // zone offset cookie, we do not need to do anything else.
  if (InitializeLocalTime())
    return;

  // Assume that txtStartDate is a TextBox control.
  if (!IsPostback)
  {
     // To display a date-time value, convert it from GMT (UTC)
     // to local time.
     DateTime startDate = GetStartDateFromDB(...);
     txtStartDate.Text  = FormatLocalDate(startDate);
     ...
  }
  else
  {
     // To save a date-time value, convert it from local
     // time to GMT (UTC).
     DateTime tempDate  = DateTime.Parse(txtStartDate.Text);
     DateTime startDate = ConvertLocalTimeToUtc(tempDate);
     SaveStartDateInDB(startDate, ...);
     ...
  }
}
...
}

Si necesita más detalles, consulte It & # 8217; s About Time : Localización del tiempo en el artículo de aplicaciones ASP.NET (lo siento, pero no tengo un enlace directo al artículo en el sitio del editor, ya que asp.netPRO restringe el acceso solo a suscriptores pagos; hay enlaces a copias en PDF, aunque). Desearía poder publicar la muestra del artículo, pero no quiero violar los derechos de autor; sin embargo, aquí hay un proyecto para construir una biblioteca auxiliar que tiene todas las funcionalidades y documentación necesarias (solo ignora las cosas que no necesitas).

ACTUALIZACIÓN: El artículo ha sido publicado en línea con un proyecto de muestra por el nuevo editor aquí .

El problema con todas las respuestas hasta ahora es que no tienen en cuenta lo que Prashant está tratando de lograr. Si el usuario de su sistema el día anterior a los cambios de horario de verano tiene una compensación de +12 y establece un recordatorio para el día siguiente, su compensación cuando se supone que se activará el recordatorio será de +13.

Es por eso que solo puede usar el desplazamiento actual para algo que está sucediendo ahora. Aunque estoy de acuerdo con todos los demás en que todo el tiempo del lado del servidor (excepto posiblemente aquellos que se usan solo para visualización) se debe almacenar en UTC.

Es posible que desee ver el uso de DateTimeOffset estructura en lugar de DateTime si está en el marco 2.0 o posterior.

DateTimeOffset representa un punto en el tiempo relativo a la hora UTC, por lo que debería ser más fácil trabajar en este caso.

Hay 2 pasos:

  • Detecta diferentes zonas horarias en el lado del cliente usando Javascript:

    var dt = new Date();
    var diffInMinutes = -dt.getTimezoneOffset();
    
  • Luego, en el lado del servidor, código C # para convertir la hora del servidor a la hora del cliente en función del desplazamiento de zona horaria detectado arriba:

------------------------;

string queryStr = Request.QueryString["diffInMinutes"];
int diffInMinutes = 0;
if (Int32.TryParse(queryStr, out diffInMinutes))
{
    clientTime = serverTime.ToUniversalTime().AddMinutes(diffInMinutes);
}

Básicamente, todo lo que necesita hacer es agregar el desplazamiento (horas + minutos) a la hora local que el usuario ha ingresado. Agregar el desplazamiento básicamente le da una fecha y hora en la zona horaria UTC (básicamente GMT).

Por lo general, es más fácil estandarizar todos sus tiempos a UTC, para que la lógica de su aplicación no tenga que lidiar con las compensaciones.

Esta página tiene algunos buenos ejemplos: http://msdn.microsoft .com / es-es / biblioteca / bb546099.aspx

El problema es que la compensación de UTC variará en diferentes épocas del año, cada zona horaria tiene sus propias reglas. (Aprendí esto de la manera difícil al desarrollar la aplicación de programación de salas de reuniones).

Parece que hay soporte incorporado aquí: http : //msdn.microsoft.com/en-us/library/system.timezoneinfo.converttime.aspx

No lo he probado yo mismo, pero parece prometer la conversión correcta, lo que representa el horario de verano.

Si no, aquí hay una herramienta comercial (costosa) que he usado: http: //www.worldtimeserver .com / time_zone_guide /

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top