Fecha y hora de conversión de la zona horaria a la zona horaria en el servidor sql

Tengo una columna de marca de tiempo de UNIX en mi tabla de base de datos, que proviene de un sistema que se encuentra en la zona horaria de Kuwait.

La zona horaria de mi servidor de base de datos es Eastern Time US & Canada . Ahora necesito convertir la marca de tiempo UNIX en el valor de la fecha de la zona horaria de Kuwait usando una consulta SQL.

¿Alguien puede decirme cómo puedo convertir esta marca de tiempo de UNIX en un valor de fecha de la zona horaria de Kuwait?

Las marcas de tiempo de Unix son un número entero de segundos desde el 1 de enero de 1970 UTC.

Suponiendo que quiere decir que tiene una columna entera en su base de datos con este número, entonces la zona horaria de su servidor de base de datos es irrelevante.

Primero convierta la marca de tiempo en un tipo de datetime y datetime :

 SELECT DATEADD(second, yourTimeStamp, '1970-01-01') 

Esta será la datetime UTC que corresponde a su marca de tiempo.

Entonces necesita saber cómo ajustar este valor a su zona horaria objective. En gran parte del mundo, una sola zona puede tener múltiples compensaciones, debido al horario de verano.

Desafortunadamente, SQL Server no tiene capacidad para trabajar zonas horarias de trabajo directamente. Entonces, si estuvieras, por ejemplo, usando la hora de los Estados Unidos en el Pacífico, no tendrías forma de saber si restarías 7 horas u 8 horas. Otras bases de datos (Oracle, Postgres, MySql, etc.) tienen formas integradas para manejar esto, pero lamentablemente SQL Server no lo hace. Entonces, si está buscando una solución de propósito general, deberá hacer una de las siguientes cosas:

  • Importe datos de zona horaria en una tabla y mantenga esa tabla a medida que cambian las reglas de zona horaria. Use esa tabla con un montón de lógica personalizada para resolver el desplazamiento de una fecha determinada.

  • Use xp_regread para obtener las claves de registro de Windows que contienen datos de zona horaria, y nuevamente use una gran cantidad de lógica personalizada para resolver el desplazamiento de una fecha en particular. Por supuesto, xp_regread es algo malo que hacer, requiere ciertos permisos otorgados y no es compatible o no es un documento.

  • Escriba una función SQLCLR que use la clase TimeZoneInfo en .Net. Desafortunadamente, esto requiere un ensamblaje SQLCLR “inseguro” y puede causar que sucedan cosas malas.

En mi humilde opinión, ninguno de estos enfoques es muy bueno, y no hay una buena solución para hacer esto directamente en SQL. La mejor solución sería devolver el valor UTC (el entero original o la datetime en UTC) al código de la aplicación llamante y en su lugar realizar la conversión de zona horaria (con, por ejemplo, TimeZoneInfo en .Net o mecanismos similares en otros plataformas).

SIN EMBARGO, has tenido la suerte de que Kuwait está (y siempre ha estado) en una zona que no cambia con el horario de verano. Siempre ha sido UTC + 03: 00. Entonces, simplemente puede agregar tres horas y devolver el resultado:

 SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01')) 

Pero reconozca que esta no es una solución de propósito general que funcionará en cualquier zona horaria.

Si lo desea, podría devolver uno de los otros tipos de datos de SQL, como datetimeoffset , pero esto solo lo ayudará a reflejar que el valor está en tres horas para cualquiera que lo mire. No hará que el proceso de conversión sea diferente o mejor.


Respuesta actualizada

Creé un proyecto para admitir zonas horarias en SQL Server. Puede instalarlo desde aquí . Entonces simplemente puede convertir así:

 SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait') 

Puede usar cualquier zona horaria de la base de datos IANA tz , incluidas las que utilizan el horario de verano.

Todavía puede usar el método que mostré arriba para convertir de una marca de tiempo de Unix. Poniéndolos a ambos juntos:

 SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait') 

Actualizado nuevamente

Con SQL Server 2016, ahora hay soporte integrado para zonas horarias con la statement AT TIME ZONE . Esto también está disponible en Azure SQL Database (v12).

 SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time' 

Más ejemplos en este anuncio.