Mi servidor de desarrollo local está en el Medio Oriente, pero mi servidor de producción está en el Reino Unido.
Necesito mostrar la fecha al usuario en su zona horaria. Por ejemplo, si un usuario está en Arabia Saudita, entonces necesito mostrar la hora de acuerdo con el formato de Arabia Saudita.
¿Debo crear una nueva tabla de base de datos llamada TimeZone y guardar la hora en UTC?
sql-server
sql-server-2008
timezone
usuario960567
fuente
fuente
Respuestas:
No hay una solución rápida para esto, desafortunadamente. La internacionalización de una aplicación debe ser parte de las primeras discusiones de diseño, ya que realmente va al núcleo de muchas áreas diferentes, incluidas las comparaciones de fecha / hora y el formato de salida.
De todos modos, para seguir el camino de Hacer lo correcto, es esencial almacenar la información de la zona horaria con la hora . En otras palabras, darse cuenta de que la fecha / hora no
20130407 14:50
tiene sentido sin (a) incluir el desplazamiento UTC actual de la zona horaria (nota 1) , o (b) garantizar que toda la lógica que inserte estos valores primero se convierta en un cierto desplazamiento fijo ( muy probablemente 0). Sin ninguna de esas cosas, dos valores de tiempo dados son incomparables y los datos están corruptos . (El último método es jugar con fuego (nota 2) , por cierto; no hagas eso).En SQL Server 2008+, puede almacenar el desplazamiento con el tiempo directamente utilizando el
datetimeoffset
tipo de datos. (Para completar, en 2005 y antes, agregaría una segunda columna para almacenar el valor de compensación UTC actual (en minutos)).Esto facilita la aplicación de tipo escritorio, ya que estas plataformas normalmente tienen mecanismos para convertir automáticamente una fecha / hora + zona horaria a una hora local y luego formatear para la salida, todo en función de la configuración regional del usuario.
Para la web, que es una arquitectura intrínsecamente desconectada, incluso con los datos de fondo configurados correctamente, es más complejo porque necesita información sobre el cliente para poder realizar la conversión y / o formateo. Esto generalmente se hace a través de la configuración de preferencias del usuario (la aplicación convierte / formatea cosas antes de la salida), o simplemente muestra cosas con el mismo formato fijo y desplazamiento de zona horaria para todos (que es lo que hace actualmente la plataforma Stack Exchange).
Puede ver cómo si los datos de fondo no están configurados correctamente, muy rápidamente se volverá complicado y complicado. No recomendaría ir por ninguno de esos caminos porque terminarás con más problemas en el futuro.
Nota 1:
El desplazamiento UTC de una zona horaria no es fijo: considere el horario de verano donde el desplazamiento UTC de una zona varía en más o menos una hora. Además, las fechas de horario de verano de las zonas varían regularmente. Por lo tanto, usar
datetimeoffset
(o una combinación delocal time
yUTC offset at that time
) da como resultado la máxima recuperación de información.Nota 2:
Se trata de controlar las entradas de datos. Si bien no hay una forma infalible de validar los valores entrantes, es mejor aplicar un estándar simple que no implique cálculos. Si una API pública espera un tipo de datos que incluya un desplazamiento, ese requisito será claro para la persona que llama.
Si ese no fuera el caso, la persona que llama tiene que confiar en la documentación (si la leyó), o el cálculo se realiza incorrectamente, etc. Hay menos modos de falla / error cuando se requiere un desplazamiento, en particular para un sistema distribuido ( o incluso solo web / base de datos en servidores separados como el caso aquí).
Almacenar el desplazamiento de todos modos mata a dos pájaros de un tiro; e incluso si eso no se requiere ahora , hace que la posibilidad esté disponible más adelante si es necesario. Es cierto que ocupa más espacio de almacenamiento, pero creo que vale la pena el intercambio porque los datos se pierden si nunca se registran en primer lugar.
fuente
datetimeoffset
significa "esta es la hora local del usuario / computadora cuando sucedió la cosa" - no necesitamos saber si el horario de verano estaba vigente o no, porque el desplazamiento UTC dado siempre está ahí (incrustado dentro deldatetimeoffset
valor).He desarrollado una solución integral para la conversión de zona horaria en SQL Server. Consulte Soporte de zona horaria de SQL Server en GitHub .
Maneja adecuadamente las conversiones entre zonas horarias y hacia y desde UTC, incluido el horario de verano.
Es similar en concepto a la solución "T-SQL Toolbox" descrita en la respuesta de adss, pero utiliza las zonas horarias más comunes de IANA / Olson / TZDB en lugar de las de Microsoft, e incluye utilidades para mantener los datos mantenidos como nuevas versiones del TZDB salir.
Ejemplo de uso (para responder al OP):
Consulte el archivo Léame en GitHub para obtener API adicionales y explicaciones detalladas.
Además, tenga en cuenta que, dado que se trata de una solución basada en UDF, no está diseñada con el rendimiento como objetivo principal. Aún sería mejor si esta funcionalidad se integrara en SQL Server, de manera similar a cómo
CONVERT_TZ
existe la función en Oracle y MySQL.fuente
SQL Server realizó modificaciones desde 2005 en adelante, donde la zona horaria interna se guarda en UTC. Esto se debió en gran medida a la geo-replicación y a los proyectores de alta disponibilidad que implican el envío de registros, y el hecho de que los tiempos de envío de registros se hayan guardado en diferentes zonas horarias hizo que fuera imposible para el antiguo método restaurarlos.
Por lo tanto, guardar todo internamente en tiempo UTC permitió que SQL Server funcionara bien globalmente. Esta es una de las razones por las cuales el ahorro de luz diurna es un poco difícil de manejar en Windows, porque otros productos de MS como Outlook también guardan la fecha / hora internamente como UTC y crean un desplazamiento que necesita ser reparado.
Trabajo en una compañía donde tenemos miles de servidores (no servidores MS SQL, sino todo tipo de servidores) repartidos por todo el mundo, y si no forzáramos específicamente que todo fuera por UTC, todos nos volveríamos locos muy rápidamente.
fuente
Desarrollé y publiqué el proyecto "T-SQL Toolbox" en codeplex para ayudar a cualquiera que tenga dificultades con el manejo de fecha y hora y zona horaria en SQL Server. Es de código abierto y completamente gratuito.
Ofrece UDF de conversión de fecha y hora fáciles utilizando T-SQL simple con tablas de configuración adicionales listas para usar.
En su ejemplo, puede usar la siguiente muestra:
Esto devolverá el valor de fecha y hora convertido para su usuario.
Se puede encontrar una lista de todas las zonas horarias admitidas en la tabla "DateTimeUtil.Timezone" también incluida en la base de datos de T-SQL Toolbox.
fuente
Es posible que me falte algo obvio, pero si todo lo que desea hacer es mostrar la fecha utilizando la zona horaria del usuario y el formato de idioma, la forma más simple es almacenar siempre las fechas en UTC en la base de datos y dejar que la aplicación cliente se convierta de UTC a local zona horaria y utilice la configuración regional del usuario para formatear la fecha en consecuencia.
fuente