sql >> Database >  >> RDS >> Sqlserver

De Unix-tijdstempel retourneren in SQL Server (T-SQL)

Het is je misschien opgevallen dat SQL Server geen equivalent heeft van MySQL's UNIX_TIMESTAMP() functie.

Het is echter niet zo moeilijk om de Unix-tijdstempel in SQL Server te retourneren.

De Unix-tijdstempel (ook bekend als Unix Epoch-tijd, Unix-tijd of POSIX-tijd) is gewoon het aantal seconden dat is verstreken sinds 00:00:00 donderdag 1 januari 1970 Coordinated Universal Time (UTC). Daarom kunnen we in SQL Server een aantal T-SQL-functies gebruiken om dit terug te geven.

SQL Server Unix-tijdstempel

Hier leest u hoe u de Unix-tijdstempel in SQL Server kunt retourneren.

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

Resultaat:

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

We kunnen dus de DATEDIFF() . gebruiken functie om het verschil in seconden tussen 1970-01-01 en nu te retourneren. We gebruiken de GETUTCDATE() functie om de huidige datum en tijd in UTC-tijd terug te geven.

Deze code werkt tot het jaar 2038 (‘2038-01-19 03:14:07’ om precies te zijn). Voor Unix-tijdstempels daarna moet u de code enigszins wijzigen. Als je een Unix-tijdstempel na die datum nodig hebt, lees dan verder.

Equivalent van MySQL Unix-tijdstempel

Ter vergelijking:als ik MySQL's UNIX_TIMESTAMP() . gebruik op precies hetzelfde moment krijg ik dit:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Resultaat:

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

Zelfde resultaat. MySQL retourneert het resultaat als een geheel getal zonder teken. Als het (optionele) argument date echter wordt doorgegeven, ondersteunt het hetzelfde bereik als de TIMESTAMP gegevenstype.

Geef de milliseconden terug

Als u een Unix-tijdstempel met hogere precisie moet retourneren, bijvoorbeeld het aantal milliseconden sinds '1970-01-01 00:00:00.000' UTC, moet u de DATEDIFF() omwisselen functie voor DATEDIFF_BIG() .

Dit komt omdat DATEDIFF() retourneert een int , wat te klein is om het aantal milliseconden sinds 1970 aan te kunnen. De DATEDIFF_BIG() functie aan de andere kant, retourneert een ondertekende bigint , wat meer dan genoeg is om milliseconden te verwerken.

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

Resultaat:

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

Geef de nanoseconden terug

Hier is nog een voorbeeld, dit keer helemaal tot aan de nanoseconden sinds '1970-01-01 00:00:00.0000000' UTC.

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

Resultaat:

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

Het probleem van het jaar 2038

Het retourneren van milliseconden, microseconden en nanoseconden is allemaal goed en wel, maar strikt genomen is het geen echte Unix Epoch-tijd. Unix Epoch-tijd is het aantal seconden sinds ‘1970-01-01 00:00:00’.

Echter, de DATEDIFF_BIG() kan nog steeds van pas komen bij het terugkeren van de strikte Unix Epoch-tijd. Het kan met name uw database helpen het 2038-probleem op te lossen. In dit geval moet alles na '2038-01-19 03:14:07' worden geretourneerd als een bigint (een geheel getal van 8 bytes). Dit komt omdat het aantal seconden te groot zal zijn voor een int gegevenstype (een geheel getal van 4 bytes). De int gegevenstype gaat slechts tot 2.147.483.647, terwijl een grote gaat tot 9.223.372.036.854.775.807.

Gebruik daarom de DATEDIFF_BIG() om Unix-tijdstempels na '2038-01-19 03:14:07' te retourneren functie in plaats van DATEDIFF() .

Om dit te demonstreren, is hier een voorbeeld van het gebruik van DATEDIFF() om de Unix-tijd op precies die datum/tijd terug te geven:

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

Resultaat:

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

Tot nu toe, zo goed. Dit resultaat valt binnen de int bereik van -2.147.483.648 tot 2.147.483.647 (hoewel het precies op de bovengrens ligt), dus het juiste resultaat wordt geretourneerd.

Maar dit is wat er gebeurt als we het met één seconde verhogen:

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

Resultaat:

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.

We krijgen de fout omdat de geretourneerde waarde buiten de int . zou zijn bereik.

Dus zoals gezegd, alles wat we hoeven te doen is DATEDIFF() swap omwisselen voor DATEDIFF_BIG() :

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

Resultaat:

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

Dit zal echter niet noodzakelijkerwijs alle problemen van 2038 oplossen, aangezien de meeste potentiële problemen waarschijnlijk van het besturingssysteem zouden worden afgeleid.

Ik moet er ook op wijzen dat geen van deze codes niet per se immuun zal zijn voor het "Jaar 10.000-probleem", omdat het de datetime2 betreft. gegevenstype, met een bovenbereik van '9999-12-31'.


  1. fout:ORA-65096:ongeldige algemene gebruiker of rolnaam in oracle

  2. Tabel als argument van een PostgreSQL-functie

  3. Hoe dynamische SQL in MySQL Stored Procedure te hebben?

  4. Wat betekent Importfout:Symbool niet gevonden:_PQencryptPasswordConn en hoe los ik dit op?