Unix-Zeitstempel sind eine ganze Zahl von Sekunden seit dem 1. Januar 1970 UTC.
Angenommen, Sie meinen, Sie haben eine Integer-Spalte in Ihrer Datenbank mit dieser Nummer, dann ist die Zeitzone Ihres Datenbankservers irrelevant.
Konvertieren Sie zuerst den Zeitstempel in ein datetime
Typ:
SELECT DATEADD(second, yourTimeStamp, '1970-01-01')
Dies ist die UTC datetime
das Ihrem Zeitstempel entspricht.
Dann müssen Sie wissen, wie Sie diesen Wert an Ihre Zielzeitzone anpassen. In weiten Teilen der Welt kann eine einzelne Zone aufgrund der Sommerzeit mehrere Verschiebungen haben.
Leider hat SQL Server keine Möglichkeit, Arbeitszeitzonen direkt zu bearbeiten. Wenn Sie also beispielsweise die US-Pazifikzeit verwenden, haben Sie keine Möglichkeit zu wissen, ob Sie 7 Stunden oder 8 Stunden abziehen sollten. Andere Datenbanken (Oracle, Postgres, MySql usw.) haben eingebaute Methoden, um damit umzugehen, SQL Server leider nicht. Wenn Sie also nach einer Allzwecklösung suchen, müssen Sie einen der folgenden Schritte ausführen:
-
Importieren Sie Zeitzonendaten in eine Tabelle und pflegen Sie diese Tabelle, wenn sich die Zeitzonenregeln ändern. Verwenden Sie diese Tabelle mit einer Menge benutzerdefinierter Logik, um den Offset für ein bestimmtes Datum aufzulösen.
-
Verwenden Sie
xp_regread
um an die Windows-Registrierungsschlüssel zu gelangen, die Zeitzonendaten enthalten, und verwenden Sie erneut eine Reihe benutzerdefinierter Logik, um den Offset für ein bestimmtes Datum aufzulösen. Natürlichxp_regread
ist eine schlechte Sache, erfordert bestimmte erteilte Berechtigungen und wird nicht unterstützt oder dokumentiert. -
Schreiben Sie eine SQLCLR-Funktion, die
TimeZoneInfo
verwendet Klasse in .Net. Leider erfordert dieser eine "unsichere" SQLCLR-Assembly , und kann dazu führen, dass schlimme Dinge passieren.
IMHO ist keiner dieser Ansätze sehr gut, und es gibt keine gute Lösung, dies direkt in SQL zu tun. Die beste Lösung wäre, den UTC-Wert zurückzugeben (entweder die ursprüngliche Ganzzahl oder die datetime
um UTC) in Ihren aufrufenden Anwendungscode und führen Sie die Zeitzonenkonvertierung stattdessen dort durch (z. B. mit TimeZoneInfo
in .Net oder ähnlichen Mechanismen in anderen Plattformen).
JEDOCH - Sie haben Glück gehabt, dass Kuwait in einer Zone liegt (und immer war), in der die Sommerzeit nicht umgestellt wird. Es war immer UTC+03:00. Sie können also einfach drei Stunden hinzufügen und das Ergebnis zurückgeben:
SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01'))
Beachten Sie jedoch, dass dies keine Allzwecklösung ist, die in jeder Zeitzone funktioniert.
Wenn Sie möchten, können Sie auch einen der anderen SQL-Datentypen zurückgeben, z. B. datetimeoffset
, aber dies wird Ihnen nur dabei helfen zu bedenken, dass der Wert gegenüber jedem, der ihn sich ansieht, um drei Stunden versetzt ist. Der Konvertierungsprozess wird dadurch weder anders noch besser.
Aktualisierte Antwort
Ich habe ein Projekt zur Unterstützung von Zeitzonen in SQL Server erstellt. Sie können es von hier installieren . Dann kannst du einfach so umwandeln:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait')
Sie können jede Zeitzone aus der IANA tz-Datenbank verwenden , einschließlich derjenigen, die die Sommerzeit verwenden.
Sie können immer noch die oben gezeigte Methode verwenden, um von einem Unix-Zeitstempel zu konvertieren. Beide zusammen:
SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait')
Erneut aktualisiert
Mit SQL Server 2016 gibt es jetzt integrierte Unterstützung für Zeitzonen mit AT TIME ZONE
Aussage. Dies ist auch in Azure SQL-Datenbank (v12) verfügbar.
SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time'
Weitere Beispiele in dieser Ankündigung.