Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come convertire un timestamp Unix in un valore di data/ora in SQL Server

In SQL Server, possiamo utilizzare il metodo seguente per restituire una data e un'ora in base a un determinato timestamp Unix.

Il timestamp Unix (noto anche come Unix Epoch time, Unix time o POSIX time) è il numero di secondi trascorsi dalle 00:00:00 di giovedì 1 gennaio 1970, Coordinated Universal Time (UTC).

Esempio

Ecco un esempio di conversione di un timestamp Unix in un valore di data/ora:

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

Risultato:

2028-12-20 14:25:19.000

In questo caso, il timestamp di Unix era 1860935119, che si traduceva in una data e ora di 2028-12-20 14:25:19.000.

Data/ora corrente

Ecco un esempio che utilizza il timestamp Unix in base alla data/ora corrente:

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

Risultato:

2022-04-18 00:31:46.000

Intendiamoci, questo è superfluo, perché avremmo potuto semplicemente fare quanto segue:

SELECT GETUTCDATE();

Timestamp Unix più grandi

Di fronte a un valore di timestamp Unix più grande come il seguente:

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

Potremmo ricevere un errore di overflow come questo:

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

Questo perché il valore del timestamp Unix è maggiore di quello che può contenere un numero intero. Questo timestamp Unix contiene una precisione di nanosecondi e ha troppe cifre per un intero.

Abbiamo un paio di opzioni per affrontare questo. Un'opzione è ridurre la precisione:

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

Risultato:

2029-03-11 09:09:22.000

Qui, abbiamo usato il LEFT() funzione per restituire solo le prime dieci cifre, oltre a CONVERT() funzione per restituire un numero intero.

Se non vogliamo ridurre la precisione, possiamo fare qualcosa del genere:

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

Risultato:

2029-03-11 09:09:22.7158769