Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

So geben Sie den Unix-Zeitstempel in SQL Server (T-SQL) zurück

Sie haben vielleicht bemerkt, dass SQL Server kein Äquivalent zu UNIX_TIMESTAMP() von MySQL hat Funktion.

Es ist jedoch nicht so schwierig, den Unix-Zeitstempel in SQL Server zurückzugeben.

Der Unix-Zeitstempel (auch bekannt als Unix-Epochenzeit, Unix-Zeit oder POSIX-Zeit) ist einfach die Anzahl der Sekunden, die seit Donnerstag, 1. Januar 1970, 00:00:00 Uhr, Koordinierte Weltzeit (UTC), vergangen sind. Daher können wir in SQL Server einige T-SQL-Funktionen verwenden, um dies zurückzugeben.

SQL Server Unix-Zeitstempel

So können Sie den Unix-Zeitstempel in SQL Server zurückgeben.

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

Ergebnis:

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

Also können wir den DATEDIFF() verwenden Funktion, um die Differenz in Sekunden zwischen 1970-01-01 und jetzt zurückzugeben. Wir verwenden das GETUTCDATE() Funktion, um das aktuelle Datum und die Uhrzeit in UTC-Zeit zurückzugeben.

Dieser Code funktioniert bis zum Jahr 2038 (genauer gesagt „2038-01-19 03:14:07“). Für Unix-Zeitstempel danach müssen Sie den Code leicht ändern. Wenn Sie einen Unix-Zeitstempel nach diesem Datum benötigen, lesen Sie weiter.

MySQL-Unix-Zeitstempel-Äquivalent

Zum Vergleich, wenn ich MySQLs UNIX_TIMESTAMP() ausführe genau zur gleichen Zeit erhalte ich Folgendes:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Ergebnis:

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

Gleiches Ergebnis. MySQL gibt das Ergebnis als vorzeichenlose Ganzzahl zurück. Wenn jedoch das (optionale) Datumsargument übergeben wird, unterstützt es denselben Bereich wie TIMESTAMP Datentyp.

Gib die Millisekunden zurück

Wenn Sie einen Unix-Zeitstempel mit höherer Genauigkeit zurückgeben müssen, sagen wir die Anzahl der Millisekunden seit „1970-01-01 00:00:00.000“ UTC müssen Sie DATEDIFF() austauschen Funktion für DATEDIFF_BIG() .

Das liegt daran, dass DATEDIFF() gibt ein int zurück , der zu klein ist, um die Anzahl der Millisekunden seit 1970 zu verarbeiten. Der DATEDIFF_BIG() Funktion hingegen gibt ein vorzeichenbehaftetes bigint zurück , was mehr als genug ist, um Millisekunden zu verarbeiten.

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

Ergebnis:

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

Gib die Nanosekunden zurück

Hier ist ein weiteres Beispiel, diesmal bis zu den Nanosekunden seit „1970-01-01 00:00:00.0000000“ UTC.

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

Ergebnis:

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

Das Jahr-2038-Problem

Die Rückgabe von Millisekunden, Mikrosekunden und Nanosekunden ist gut und schön, aber genau genommen ist es keine echte Unix-Epochenzeit. Die Unix-Epochenzeit ist die Anzahl von Sekunden seit ‘1970-01-01 00:00:00’.

Der DATEDIFF_BIG() kann immer noch nützlich sein, wenn Sie die strenge Unix-Epochenzeit zurückgeben. Insbesondere könnte es Ihrer Datenbank helfen, das 2038-Problem zu überwinden. In diesem Fall muss alles nach „2038-01-19 03:14:07“ als bigint zurückgegeben werden (eine 8-Byte-Ganzzahl). Dies liegt daran, dass die Anzahl der Sekunden für ein int zu groß ist Datentyp (eine 4-Byte-Ganzzahl). Der int Der Datentyp geht nur bis 2.147.483.647, wohingegen ein bigint steigt auf 9.223.372.036.854.775.807.

Um Unix-Zeitstempel nach „2038-01-19 03:14:07“ zurückzugeben, verwenden Sie daher DATEDIFF_BIG() Funktion anstelle von DATEDIFF() .

Um dies zu demonstrieren, ist hier ein Beispiel für die Verwendung von DATEDIFF() um die Unix-Zeit genau zu diesem Datum/dieser Uhrzeit zurückzugeben:

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

Ergebnis:

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

So weit, ist es gut. Dieses Ergebnis befindet sich innerhalb von int Bereich von -2.147.483.648 bis 2.147.483.647 (obwohl es genau an der Obergrenze liegt), sodass das richtige Ergebnis zurückgegeben wird.

Aber hier ist, was passiert, wenn wir es um eine Sekunde erhöhen:

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

Ergebnis:

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.

Wir erhalten den Fehler, weil der zurückgegebene Wert außerhalb von int liegen würde Bereich.

Wie bereits erwähnt, müssen wir also nur DATEDIFF() austauschen für DATEDIFF_BIG() :

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

Ergebnis:

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

Dies wird jedoch nicht unbedingt alle Probleme des Jahres 2038 lösen, da die meisten potenziellen Probleme wahrscheinlich vom Betriebssystem herrühren würden.

Ich sollte auch darauf hinweisen, dass keiner dieser Codes unbedingt gegen das „Jahr-10.000-Problem“ gefeit sein wird, da es um datetime2 geht Datentyp, der einen oberen Bereich von „9999-12-31“ hat.