sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo convertir una marca de tiempo de Unix en un valor de fecha/hora en SQL Server

En SQL Server, podemos usar el siguiente método para devolver una fecha y hora en función de una marca de tiempo de Unix determinada.

La marca de tiempo de Unix (también conocida como hora de época de Unix, hora de Unix o hora POSIX) es la cantidad de segundos que han transcurrido desde las 00:00:00 del jueves 1 de enero de 1970, hora universal coordinada (UTC).

Ejemplo

Este es un ejemplo de cómo convertir una marca de tiempo de Unix en un valor de fecha/hora:

SELECT DATEADD(s, 1860935119, '1970-01-01');

Resultado:

2028-12-20 14:25:19.000

En este caso, la marca de tiempo de Unix era 1860935119, que se tradujo en una fecha y hora de 2028-12-20 14:25:19.000.

Fecha/hora actual

Aquí hay un ejemplo que usa la marca de tiempo de Unix basada en la fecha/hora actual:

SELECT DATEADD(s, DATEDIFF(s, '1970-01-01', GETUTCDATE()), '1970-01-01');

Resultado:

2022-04-18 00:31:46.000

Eso sí, esto es superfluo, porque podríamos haber hecho lo siguiente:

SELECT GETUTCDATE();

Marcas de tiempo Unix más grandes

Cuando se enfrenta a un valor de marca de tiempo de Unix más grande como el siguiente:

SELECT DATEADD(s, 1867914562715876900, '1970-01-01');

Podríamos obtener un error de desbordamiento como este:

Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type int.

Esto se debe a que el valor de la marca de tiempo de Unix es mayor que lo que puede contener un número entero. Esta marca de tiempo de Unix contiene una precisión de nanosegundos y tiene demasiados dígitos para un número entero.

Tenemos un par de opciones para lidiar con esto. Una opción es reducir la precisión:

DECLARE @ts bigint = 1867914562715876900;
SELECT DATEADD(s, CONVERT(int, LEFT(@ts, 10)), '1970-01-01');

Resultado:

2029-03-11 09:09:22.000

Aquí, usamos LEFT() función para devolver solo los primeros diez dígitos, así como el CONVERT() función para devolver un número entero.

Si no queremos reducir la precisión, podemos hacer algo como esto:

DECLARE @ts bigint = 1867914562715876900;
SELECT DATEADD(
    ns, 
    @ts % 1000000000, 
    DATEADD( s, @ts / 1000000000, CAST('1970-01-01' as datetime2(7)) )
    );

Resultado:

2029-03-11 09:09:22.7158769