Možná jste si všimli, že SQL Server nemá ekvivalent UNIX_TIMESTAMP()
MySQL funkce.
Není však tak obtížné vrátit Unixové časové razítko na SQL Server.
Unixové časové razítko (také známé jako Unix Epoch time, Unix time nebo POSIX time) je jednoduše počet sekund, které uplynuly od 00:00:00 čtvrtek 1. ledna 1970 koordinovaného světového času (UTC). Proto v SQL Server můžeme použít několik funkcí T-SQL, abychom to vrátili.
Časové razítko SQL Server Unix
Zde je návod, jak můžete vrátit Unixové časové razítko na SQL Server.
SELECT DATEDIFF(SECOND,'1970-01-01', GETUTCDATE()) AS 'SQL Server Result';
Výsledek:
+---------------------+ | SQL Server Result | |---------------------| | 1560833178 | +---------------------+
Můžeme tedy použít DATEDIFF()
funkce, která vrátí rozdíl v sekundách mezi 1. 1. 1970 a nyní. Používáme GETUTCDATE()
funkce vrátit aktuální datum a čas v čase UTC.
Tento kód bude fungovat až do roku 2038 (přesněji ‚2038-01-19 03:14:07‘). U časových razítek Unix poté budete muset kód mírně upravit. Pokud potřebujete unixové časové razítko po tomto datu, čtěte dále.
Ekvivalent MySQL Unix Timestamp
Pro srovnání, když spustím UNIX_TIMESTAMP()
MySQL přesně ve stejnou dobu dostanu toto:
SELECT UNIX_TIMESTAMP() AS 'MySQL Result';
Výsledek:
+--------------+ | MySQL Result | +--------------+ | 1560833178 | +--------------+
Stejný výsledek. MySQL vrátí výsledek jako celé číslo bez znaménka. Pokud je však předán (volitelný) argument data, podporuje stejný rozsah jako TIMESTAMP
datový typ.
Vrátí milisekundy
Pokud potřebujete vrátit unixové časové razítko s vyšší přesností, řekněme počet milisekund od „1970-01-01 00:00:00.000“ UTC budete muset vyměnit DATEDIFF()
funkce pro DATEDIFF_BIG()
.
Důvodem je DATEDIFF()
vrátí int , která je příliš malá na to, aby zvládla počet milisekund od roku 1970. DATEDIFF_BIG()
funkce na druhé straně vrací podepsaný bigint , což je více než dost na to, aby zvládlo milisekundy.
SELECT DATEDIFF_BIG(MILLISECOND,'1970-01-01 00:00:00.000', SYSUTCDATETIME()) Milliseconds;
Výsledek:
+----------------+ | Milliseconds | |----------------| | 1560835305461 | +----------------+
Vraťte nanosekundy
Zde je další příklad, tentokrát až do nanosekund od ‚1970-01-01 00:00:00.0000000‘ UTC.
SELECT DATEDIFF_BIG(NANOSECOND,'1970-01-01 00:00:00.0000000', SYSUTCDATETIME()) Nanoseconds;
Výsledek:
+---------------------+ | Nanoseconds | |---------------------| | 1560835321500279300 | +---------------------+
Problém roku 2038
Vrácení milisekund, mikrosekund a nanosekund je dobré a dobré, ale přísně vzato to není pravý čas Unixové epochy. Unix Epoch time je počet sekund od ‚1970-01-01 00:00:00‘.
Nicméně DATEDIFF_BIG()
se stále může hodit při návratu přísného času unixové epochy. Zejména by to mohlo pomoci vaší databázi překonat problém roku 2038. V tomto případě bude vše po „2038-01-19 03:14:07“ nutné vrátit jako bigint (8 bajtové celé číslo). Je to proto, že počet sekund bude pro int příliš velký datový typ (4bajtové celé číslo). int datový typ se zvýší pouze na 2 147 483 647, zatímco bigint stoupá na 9 223 372 036 854 775 807.
Proto, chcete-li vrátit časová razítka Unixu za „2038-01-19 03:14:07“, použijte DATEDIFF_BIG()
funkce namísto DATEDIFF()
.
Abychom to demonstrovali, zde je příklad použití DATEDIFF()
vrátit Unixový čas přesně v tomto datu/čase:
SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:07') AS 'Unix Epoch time';
Výsledek:
+-------------------+ | Unix Epoch time | |-------------------| | 2147483647 | +-------------------+
Zatím je vše dobré. Tento výsledek je v rámci int rozsah -2 147 483 648 až 2 147 483 647 (ačkoli je to přesně na horní hranici), takže je vrácen správný výsledek.
Ale tohle se stane, když ji zvýšíme o jednu sekundu:
SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';
Výsledek:
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.
Dostaneme chybu, protože vrácená hodnota by byla mimo int rozsah.
Jak již bylo řečeno, vše, co musíme udělat, je prohodit DATEDIFF()
pro DATEDIFF_BIG()
:
SELECT DATEDIFF_BIG(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';
Výsledek:
+-------------------+ | Unix Epoch time | |-------------------| | 2147483648 | +-------------------+
To však nutně nevyřeší všechny problémy roku 2038, protože většina potenciálních problémů bude pravděpodobně odvozena od operačního systému.
Měl bych také zdůraznit, že žádný z tohoto kódu nebude nutně imunní vůči „problému roku 10 000“, protože zahrnuje datetime2 datový typ, který má horní rozsah „9999-12-31“.