sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man returnerar Unix-tidsstämpeln i SQL Server (T-SQL)

Du kanske har märkt att SQL Server inte har en motsvarighet till MySQL:s UNIX_TIMESTAMP() funktion.

Det är dock inte så svårt att returnera Unix-tidsstämpeln i SQL Server.

Unix-tidsstämpeln (även känd som Unix Epoch-tid, Unix-tid eller POSIX-tid) är helt enkelt antalet sekunder som har förflutit sedan 00:00:00 torsdagen den 1 januari 1970, Coordinated Universal Time (UTC). Därför kan vi i SQL Server använda ett par T-SQL-funktioner för att returnera detta.

SQL Server Unix Tidsstämpel

Så här kan du returnera Unix-tidsstämpeln i SQL Server.

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

Resultat:

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

Så vi kan använda DATEDIFF() funktion för att returnera skillnaden i sekunder mellan 1970-01-01 och nu. Vi använder GETUTCDATE() funktion för att returnera aktuellt datum och tid i UTC-tid.

Denna kod kommer att fungera fram till år 2038 ('2038-01-19 03:14:07' för att vara exakt). För Unix-tidsstämplar efter det måste du ändra koden något. Om du behöver en Unix-tidsstämpel efter det datumet, läs vidare.

MySQL Unix tidsstämpel ekvivalent

För en jämförelse, om jag kör MySQL:s UNIX_TIMESTAMP() exakt samtidigt får jag detta:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Resultat:

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

Samma resultat. MySQL returnerar resultatet som ett heltal utan tecken. Men om (valfritt) datumargumentet skickas, stöder det samma intervall som TIMESTAMP datatyp.

Returnera millisekunderna

Om du behöver returnera en Unix-tidsstämpel med högre precision, t.ex. antalet millisekunder sedan ‘1970-01-01 00:00:00.000’ UTC måste du byta DATEDIFF() funktion för DATEDIFF_BIG() .

Detta beror på att DATEDIFF() returnerar en int , vilket är för litet för att hantera antalet millisekunder sedan 1970. DATEDIFF_BIG() funktion å andra sidan, returnerar en signerad bigint , vilket är mer än tillräckligt för att hantera millisekunder.

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

Resultat:

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

Återställ nanosekunderna

Här är ett annat exempel, den här gången går det hela vägen upp till nanosekunderna sedan '1970-01-01 00:00:00.0000000' UTC.

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

Resultat:

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

Årsproblemet 2038

Att returnera millisekunder, mikrosekunder och nanosekunder är bra och bra, men strängt taget är det inte sann Unix Epoch-tid. Unix Epoch-tid är antalet sekunder sedan '1970-01-01 00:00:00'.

Men DATEDIFF_BIG() kan fortfarande komma väl till pass när man returnerar strikt Unix Epoch-tid. I synnerhet kan det hjälpa din databas att övervinna 2038-problemet. I det här fallet måste allt efter "2038-01-19 03:14:07" returneras som en bigint (ett heltal på 8 byte). Detta beror på att antalet sekunder kommer att vara för stort för en int datatyp (ett heltal på 4 byte). int datatypen går bara upp till 2 147 483 647, medan en bigint går upp till 9 223 372 036 854 775 807.

Därför, för att returnera Unix-tidsstämplar efter "2038-01-19 03:14:07", använd DATEDIFF_BIG() funktion istället för DATEDIFF() .

För att demonstrera detta, här är ett exempel på hur du använder DATEDIFF() för att returnera Unix-tid vid exakt detta datum/tid:

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

Resultat:

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

Än så länge är allt bra. Detta resultat ligger inom int intervallet -2 147 483 648 till 2 147 483 647 (även om det är precis vid den övre gränsen) så att det korrekta resultatet returneras.

Men här är vad som händer om vi ökar den med en sekund:

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

Resultat:

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.

Vi får felet eftersom det returnerade värdet skulle vara utanför int intervall.

Så som sagt, allt vi behöver göra är att byta DATEDIFF() för DATEDIFF_BIG() :

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

Resultat:

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

Detta kommer dock inte nödvändigtvis att lösa alla år 2038-problem, eftersom de flesta potentiella problem förmodligen skulle härledas från operativsystemet.

Jag bör också påpeka att ingen av denna kod inte nödvändigtvis kommer att vara immun mot "År 10 000-problemet", eftersom det involverar datetime2 datatyp, som har ett övre intervall på "9999-12-31".


  1. Erlang och dess konsumtion av Heap Memory

  2. Postgres UTC datumformat &epok cast, tecken inversion

  3. Om Neo4j

  4. kommaseparerad sträng av valda värden i mysql