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

Konvertierung von Datum und Uhrzeit von Zeitzone zu Zeitzone in SQL Server

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ürlich xp_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.