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

Konvertieren Sie ein Datum in eine andere Zeitzone in SQL Server

Die AT TIME ZONE -Klausel wurde in SQL Server 2016 eingeführt, um ein Datum in ein datetimeoffset umzuwandeln Wert in einer Zielzeitzone.

Diese Funktion ähnelt einigen anderen T-SQL-Funktionen, wie z. B. SWITCHOFFSET() und TODATETIMEOFFSET() , jedoch die AT TIME ZONE -Klausel ermöglicht/(erfordert) die Angabe des Zeitzonen-Offsets anhand des Namens anstelle eines tatsächlichen Offset-Werts.

In diesem Artikel wird untersucht, wie AT TIME ZONE funktioniert und erklärt seine Vorteile im Vergleich zu den anderen genannten Funktionen.

Anwendungsbeispiel

Hier ist ein einfaches Beispiel dafür, wie der AT TIME ZONE Klausel funktioniert.

DECLARE @dto datetimeoffset = '2020-04-01 00:00:00.0000000 +00:00';
SELECT
  @dto AS [Original],
  @dto AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time];

Ergebnis (bei vertikaler Ausgabe):

Original | 2020-04-01 00:00:00.0000000 +00:00
NZ Time  | 2020-04-01 13:00:00.0000000 +13:00

Sie fragen sich vielleicht, warum Microsoft diese Funktion überhaupt eingeführt hat, wenn Sie den SWITCHOFFSET() hätten verwenden können Funktion dasselbe tun?

Nun, das können Sie nicht machen Sie genau dasselbe mit SWITCHOFFSET() .

Mit SWITCHOFFSET() , müssen Sie den tatsächlichen Zeitzonenoffset entweder im Format [+|-]TZH:TZM oder als vorzeichenbehaftete Ganzzahl (für Minuten) angeben. Das bedeutet, dass Sie den genauen Zeitzonen-Offset kennen müssen, und ob in dieser Zeitzone derzeit Sommerzeit gilt oder nicht.

Mit dem AT TIME ZONE Klausel, das müssen Sie nicht wissen. Alles, was Sie wissen müssen, ist der Name der Zeitzone (und hier erfahren Sie, wie Sie den Namen der Zeitzone erhalten).

Beispiel für die Sommerzeit

Hier ist ein Beispiel, das die Vorteile der Verwendung von AT TIME ZONE demonstriert in Bezug auf die Sommerzeit.

DECLARE @dto1 datetimeoffset, @dto2 datetimeoffset;
SET @dto1 = '2020-04-01 00:00:00.0000000 +00:00';
SET @dto2 = '2020-04-07 00:00:00.0000000 +00:00';
SELECT
  @dto1 AS [@dto1],
  @dto2 AS [@dto2],
  @dto1 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dto1],
  @dto2 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dto2];

Ergebnis (bei vertikaler Ausgabe):

@dto1          | 2020-04-01 00:00:00.0000000 +00:00
@dto2          | 2020-04-07 00:00:00.0000000 +00:00
NZ Time: @dto1 | 2020-04-01 13:00:00.0000000 +13:00
NZ Time: @dto2 | 2020-04-07 12:00:00.0000000 +12:00

In Neuseeland endet die Sommerzeit am 5. März 2020. Daher verwende ich in diesem Beispiel zwei Daten (1. März und 7. März).

Wenn ich sie in „neuseeländische Standardzeit“ umrechne, AT TIME ZONE bezieht automatisch die Sommerzeit in seine Berechnung ein und gibt das entsprechende Datum/die Uhrzeit zurück.

Wir können also sehen, dass das Datum vom 1. März einen Zeitzonenversatz von +13:00 und das Datum vom 7. März +12:00 verwendet (da die Sommerzeit am 5. März endete).

Wenn ich SWITCHOFFSET() verwendet hätte Ich hätte wissen müssen, welcher Zeitzonenoffset für jedes Datum verwendet werden soll.

DECLARE @dto1 datetimeoffset, @dto2 datetimeoffset;
SET @dto1 = '2020-04-01 00:00:00.0000000 +00:00';
SET @dto2 = '2020-04-07 00:00:00.0000000 +00:00';
SELECT
  @dto1 AS [@dto1],
  @dto2 AS [@dto2],
  SWITCHOFFSET(@dto1, '+12:00') AS [+12:00],
  SWITCHOFFSET(@dto2, '+13:00') AS [+13:00];

Ergebnis (bei vertikaler Ausgabe):

@dto1  | 2020-04-01 00:00:00.0000000 +00:00
@dto2  | 2020-04-07 00:00:00.0000000 +00:00
+12:00 | 2020-04-01 12:00:00.0000000 +12:00
+13:00 | 2020-04-07 13:00:00.0000000 +13:00

Konvertieren von Datumsangaben ohne Zeitzonenverschiebung

Sie können auch AT TIME ZONE verwenden an Daten ohne Zeitzonenverschiebung. Tatsächlich akzeptiert die Funktion jeden Ausdruck, der in smalldatetime aufgelöst werden kann , datetime , datetime2 , oder datetimeoffset Wert.

Allerdings müssen Sie dabei darauf achten, wie das Ergebnis berechnet wird. Wenn das Datum ohne Versatzinformationen bereitgestellt wird, wendet die Funktion den Versatz der Zeitzone an, wobei davon ausgegangen wird, dass das Eingabedatum in der Zielzeitzone liegt.

DECLARE @dt1 smalldatetime, @dt2 smalldatetime;
SET @dt1 = '2020-04-01 00:00:00';
SET @dt2 = '2020-04-07 00:00:00';
SELECT
  @dt1 AS [@dt1],
  @dt2 AS [@dt2],
  @dt1 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt1],
  @dt2 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt2];

Ergebnis:

@dt1          | 2020-04-01 00:00:00
@dt2          | 2020-04-07 00:00:00
NZ Time: @dt1 | 2020-04-01 00:00:00.0000000 +13:00
NZ Time: @dt2 | 2020-04-07 00:00:00.0000000 +12:00

Beachten Sie, dass die Zeitzonen-Offsets zwar wie angegeben angewendet wurden, dies jedoch keinen Einfluss auf Datum/Uhrzeit hatte. Beide resultierenden Datums-/Uhrzeitangaben haben den gleichen Wert – nur der Zeitzonen-Offset hat sich geändert.

Wenn Sie dies nicht möchten, können Sie AT TIME ZONE 'UTC' hinzufügen in den Mix, um die Originaldaten zunächst in UTC zu konvertieren, bevor sie in die gewünschte Zeitzone konvertiert werden.

DECLARE @dt1 smalldatetime, @dt2 smalldatetime;
SET @dt1 = '2020-04-01 00:00:00';
SET @dt2 = '2020-04-07 00:00:00';
SELECT
  @dt1 AS [@dt1],
  @dt2 AS [@dt2],
  @dt1 AT TIME ZONE 'UTC' AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt1],
  @dt2 AT TIME ZONE 'UTC' AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt2];

Ergebnis:

@dt1          | 2020-04-01 00:00:00
@dt2          | 2020-04-07 00:00:00
NZ Time: @dt1 | 2020-04-01 13:00:00.0000000 +13:00
NZ Time: @dt2 | 2020-04-07 12:00:00.0000000 +12:00