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

Sådan returneres Unix-tidsstemplet i SQL Server (T-SQL)

Du har måske bemærket, at SQL Server ikke har en ækvivalent til MySQL's UNIX_TIMESTAMP() funktion.

Det er dog ikke så svært at returnere Unix-tidsstemplet i SQL Server.

Unix-tidsstemplet (også kendt som Unix-epoketid, Unix-tid eller POSIX-tid) er simpelthen det antal sekunder, der er gået siden 00:00:00 torsdag den 1. januar 1970, Coordinated Universal Time (UTC). Derfor kan vi i SQL Server bruge et par T-SQL-funktioner til at returnere dette.

SQL Server Unix-tidsstempel

Sådan kan du returnere Unix-tidsstemplet i SQL Server.

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

Resultat:

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

Så vi kan bruge DATEDIFF() funktion til at returnere forskellen i sekunder mellem 1970-01-01 og nu. Vi bruger GETUTCDATE() funktion for at returnere den aktuelle dato og tid i UTC-tid.

Denne kode vil fungere indtil år 2038 ('2038-01-19 03:14:07' for at være præcis). For Unix-tidsstempler efter det, skal du ændre koden lidt. Hvis du har brug for et Unix-tidsstempel efter den dato, så læs videre.

MySQL Unix-tidsstempelækvivalent

Til sammenligning, hvis jeg kører MySQL's UNIX_TIMESTAMP() på nøjagtig samme tid får jeg dette:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Resultat:

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

Samme resultat. MySQL returnerer resultatet som et heltal uden fortegn. Men hvis det (valgfrie) dato-argument sendes, understøtter det det samme interval som TIMESTAMP datatype.

Tilbagefør millisekunderne

Hvis du har brug for at returnere et Unix-tidsstempel med højere præcision, f.eks. antallet af millisekunder siden ‘1970-01-01 00:00:00.000’ UTC, skal du bytte DATEDIFF() funktion for DATEDIFF_BIG() .

Dette er fordi DATEDIFF() returnerer en int , som er for lille til at håndtere antallet af millisekunder siden 1970. DATEDIFF_BIG() funktion på den anden side returnerer en bigint med fortegn , hvilket er mere end nok til at håndtere millisekunder.

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

Resultat:

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

Tilbagefør nanosekunderne

Her er endnu et eksempel, som denne gang går helt op til nanosekunderne siden '1970-01-01 00:00:00.0000000' UTC.

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

Resultat:

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

Året 2038-problemet

At returnere millisekunder, mikrosekunder og nanosekunder er godt og godt, men strengt taget er det ikke sand Unix Epoch-tid. Unix Epoch-tid er antallet af sekunder siden '1970-01-01 00:00:00'.

Men DATEDIFF_BIG() kan stadig komme til nytte, når du returnerer streng Unix Epoch-tid. Det kan især hjælpe din database med at overvinde 2038-problemet. I dette tilfælde skal alt efter "2038-01-19 03:14:07" returneres som en bigint (et 8 byte heltal). Dette skyldes, at antallet af sekunder vil være for stort til en int datatype (et 4 byte heltal). int datatypen går kun op til 2.147.483.647, hvorimod en bigt går op til 9.223.372.036.854.775.807.

Derfor skal du bruge DATEDIFF_BIG() for at returnere Unix-tidsstempler efter '2038-01-19 03:14:07' funktion i stedet for DATEDIFF() .

For at demonstrere dette er her et eksempel på brug af DATEDIFF() for at returnere Unix-tid på præcis den dato/tid:

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

Resultat:

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

Så langt så godt. Dette resultat er inden for int interval på -2.147.483.648 til 2.147.483.647 (selvom det er lige ved den øvre grænse), så det korrekte resultat returneres.

Men her er, hvad der sker, hvis vi øger det med et 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 fejlen, fordi den returnerede værdi ville være uden for int rækkevidde.

Så som nævnt, alt hvad vi skal gøre er at bytte DATEDIFF() for DATEDIFF_BIG() :

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

Resultat:

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

Dette vil dog ikke nødvendigvis løse alle år 2038-problemer, da de fleste potentielle problemer sandsynligvis vil være afledt af operativsystemet.

Jeg skal også påpege, at ingen af ​​denne kode ikke nødvendigvis vil være immun over for "År 10.000-problemet", fordi det involverer datetime2 datatype, som har et øvre område på '9999-12-31'.


  1. Hvordan gentager jeg et ressource-id #6 fra et MySql-svar i PHP?

  2. Hvilken kolonne skal det klyngede indeks sættes på?

  3. Konverter kommasepareret streng til array i PL/SQL

  4. Forældede funktioner til at tage ud af din værktøjskasse – Del 3