Las marcas de tiempo de Unix son números enteros de segundos desde el 1 de enero de 1970 UTC.
Suponiendo que quiere decir que tiene una columna de enteros 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 datetime
tipo:
SELECT DATEADD(second, yourTimeStamp, '1970-01-01')
Este será el UTC datetime
que corresponde a su marca de tiempo.
Entonces necesita saber cómo ajustar este valor a su zona horaria de destino. En gran parte del mundo, una sola zona puede tener múltiples compensaciones debido al horario de verano.
Desafortunadamente, SQL Server no tiene la capacidad de trabajar con zonas horarias de trabajo directamente. Entonces, si estuviera, por ejemplo, usando la hora del Pacífico de EE. UU., no tendría forma de saber si debe restar 7 u 8 horas. Otras bases de datos (Oracle, Postgres, MySql, etc.) tienen formas integradas de manejar esto, pero, por desgracia, SQL Server no. Por lo tanto, si está buscando una solución de uso general, deberá realizar una de las siguientes acciones:
-
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 en particular.
-
Usa
xp_regread
para acceder a las claves de registro de Windows que contienen datos de zona horaria y, de nuevo, usar un montón de lógica personalizada para resolver el desplazamiento de una fecha en particular. Por supuesto,xp_regread
es algo malo, requiere que se otorguen ciertos permisos y no es compatible ni documentado. -
Escriba una función SQLCLR que use
TimeZoneInfo
clase en .Net. Desafortunadamente, este requiere un ensamblado SQLCLR "inseguro" y podría 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 hacerlo directamente en SQL. La mejor solución sería devolver el valor UTC (ya sea el número entero original o el datetime
en UTC) a su código de aplicación de llamada, y haga la conversión de zona horaria allí en su lugar (con, por ejemplo, TimeZoneInfo
en .Net o mecanismos similares en otras plataformas).
SIN EMBARGO, ha tenido suerte porque Kuwait está (y siempre ha estado) en una zona que no cambia para el horario de verano. Siempre ha sido UTC+03:00. Así que 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 quisiera, podría devolver uno de los otros tipos de datos SQL, como datetimeoffset
, pero esto solo lo ayudará a reflejar que el valor tiene una compensación de tres horas para cualquiera que pueda mirarlo. 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 tz de IANA , incluidos aquellos que utilizan el horario de verano.
Todavía puede usar el método que mostré arriba para convertir desde una marca de tiempo de Unix. Juntando ambos:
SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait')
Actualizado de nuevo
Con SQL Server 2016, ahora hay soporte integrado para zonas horarias con AT TIME ZONE
declaración. Esto también está disponible en Azure SQL Database (v12).
SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time'