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

Come restituire il timestamp Unix in SQL Server (T-SQL)

Potresti aver notato che SQL Server non ha un equivalente di UNIX_TIMESTAMP() di MySQL funzione.

Tuttavia, non è così difficile restituire il timestamp Unix in SQL Server.

Il timestamp Unix (noto anche come Unix Epoch time, Unix time o POSIX time) è semplicemente il numero di secondi trascorsi dalle 00:00:00 di giovedì 1 gennaio 1970, Coordinated Universal Time (UTC). Pertanto, in SQL Server possiamo utilizzare un paio di funzioni T-SQL per restituire questo.

Data e ora di SQL Server Unix

Ecco come restituire il timestamp Unix in SQL Server.

SELECT DATEDIFF(SECOND,'1970-01-01', GETUTCDATE()) AS 'SQL Server Result';

Risultato:

+---------------------+
| SQL Server Result   |
|---------------------|
| 1560833178          |
+---------------------+

Quindi possiamo usare il DATEDIFF() funzione per restituire la differenza in secondi tra 1970-01-01 e adesso. Usiamo il GETUTCDATE() funzione per restituire la data e l'ora correnti nell'ora UTC.

Questo codice funzionerà fino all'anno 2038 ('2038-01-19 03:14:07' per la precisione). Per i timestamp Unix successivi, dovrai modificare leggermente il codice. Se hai bisogno di un timestamp Unix dopo quella data, continua a leggere.

Equivalente a timestamp MySQL Unix

Per fare un confronto, se eseguo UNIX_TIMESTAMP() di MySQL esattamente nello stesso momento, ottengo questo:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Risultato:

+--------------+
| MySQL Result |
+--------------+
|   1560833178 |
+--------------+

Stesso risultato. MySQL restituisce il risultato come un intero senza segno. Tuttavia, se viene passato l'argomento data (facoltativo), supporta lo stesso intervallo di TIMESTAMP tipo di dati.

Restituisci i millisecondi

Se devi restituire un timestamp Unix con maggiore precisione, ad esempio il numero di millisecondi dal ‘1970-01-01 00:00:00.000’ UTC, dovrai scambiare il DATEDIFF() funzione per DATEDIFF_BIG() .

Questo perché DATEDIFF() restituisce un int , che è troppo piccolo per gestire il numero di millisecondi dal 1970. Il DATEDIFF_BIG() funzione d'altra parte, restituisce un segno bigint , che è più che sufficiente per gestire i millisecondi.

SELECT DATEDIFF_BIG(MILLISECOND,'1970-01-01 00:00:00.000', SYSUTCDATETIME()) Milliseconds;

Risultato:

+----------------+
| Milliseconds   |
|----------------|
| 1560835305461  |
+----------------+

Restituisci i nanosecondi

Ecco un altro esempio, questa volta fino ai nanosecondi da "1970-01-01 00:00:00.0000000" UTC.

SELECT DATEDIFF_BIG(NANOSECOND,'1970-01-01 00:00:00.0000000', SYSUTCDATETIME()) Nanoseconds;

Risultato:

+---------------------+
| Nanoseconds         |
|---------------------|
| 1560835321500279300 |
+---------------------+

Il problema dell'anno 2038

La restituzione di millisecondi, microsecondi e nanosecondi va bene, ma a rigor di termini non è il vero tempo di Unix Epoch. Il tempo di Unix Epoch è il numero di secondi dal ‘1970-01-01 00:00:00’.

Tuttavia, il DATEDIFF_BIG() può ancora tornare utile quando si restituisce il tempo rigoroso di Unix Epoch. In particolare, potrebbe aiutare il tuo database a superare il problema del 2038. In questo caso, qualsiasi cosa successiva a "2038-01-19 03:14:07" dovrà essere restituita come bigint (un numero intero di 8 byte). Questo perché il numero di secondi sarà troppo grande per un int tipo di dati (un numero intero di 4 byte). Il int il tipo di dati arriva solo a 2.147.483.647, mentre un bigint sale a 9.223.372.036.854.775.807.

Pertanto, per restituire i timestamp Unix dopo "2038-01-19 03:14:07", utilizzare DATEDIFF_BIG() funzione invece di DATEDIFF() .

Per dimostrarlo, ecco un esempio di utilizzo di DATEDIFF() per restituire l'ora Unix esattamente a quella data/ora:

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:07') AS 'Unix Epoch time';

Risultato:

+-------------------+
| Unix Epoch time   |
|-------------------|
| 2147483647        |
+-------------------+

Fin qui tutto bene. Questo risultato è all'interno di int intervallo compreso tra -2.147.483.648 e 2.147.483.647 (sebbene sia proprio al limite superiore), quindi viene restituito il risultato corretto.

Ma ecco cosa succede se lo aumentiamo di un secondo:

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';

Risultato:

The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

Otteniamo l'errore perché il valore restituito sarebbe al di fuori di int intervallo.

Quindi, come accennato, tutto ciò che dobbiamo fare è scambiare DATEDIFF() per DATEDIFF_BIG() :

SELECT DATEDIFF_BIG(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';

Risultato:

+-------------------+
| Unix Epoch time   |
|-------------------|
| 2147483648        |
+-------------------+

Tuttavia, questo non risolverà necessariamente tutti i problemi dell'anno 2038, poiché la maggior parte dei potenziali problemi deriverebbe probabilmente dal sistema operativo.

Devo anche sottolineare che nessuno di questi codici non sarà necessariamente immune dal "Problema Anno 10.000", perché coinvolge il datetime2 tipo di dati, che ha un intervallo superiore di "9999-12-31".