AT TIME ZONE
Klauzula została wprowadzona w SQL Server 2016, aby przekonwertować datę na przesunięcie daty i godziny wartość w docelowej strefie czasowej.
Ta funkcja jest podobna do niektórych innych funkcji T-SQL, takich jak SWITCHOFFSET()
i TODATETIMEOFFSET()
, jednak AT TIME ZONE
klauzula umożliwia/(wymaga) określenie przesunięcia strefy czasowej według nazwy, zamiast rzeczywistej wartości przesunięcia.
Z tego artykułu dowiesz się, jak AT TIME ZONE
działa i wyjaśnia jego zalety w porównaniu z innymi wymienionymi funkcjami.
Przykład użycia
Oto podstawowy przykład tego, jak AT TIME ZONE
klauzula działa.
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];
Wynik (przy użyciu wyjścia pionowego):
Original | 2020-04-01 00:00:00.0000000 +00:00 NZ Time | 2020-04-01 13:00:00.0000000 +13:00
Być może zastanawiasz się, dlaczego Microsoft wprowadził tę funkcję, skoro można było użyć SWITCHOFFSET()
funkcja robi to samo?
Cóż, nie możesz faktycznie zrób dokładnie to samo z SWITCHOFFSET()
.
Za pomocą SWITCHOFFSET()
, należy podać rzeczywiste przesunięcie strefy czasowej w formacie [+|-]TZH:TZM lub jako liczbę całkowitą ze znakiem (w minutach). Oznacza to, że musisz znać dokładne przesunięcie strefy czasowej i czy w tej strefie czasowej obowiązuje obecnie czas letni.
Z AT TIME ZONE
klauzula, nie musisz tego wiedzieć. Wszystko, co musisz wiedzieć, to nazwa strefy czasowej (a oto jak uzyskać nazwę strefy czasowej).
Przykład czasu letniego
Oto przykład, który pokazuje korzyści płynące z używania AT TIME ZONE
w odniesieniu do czasu letniego.
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];
Wynik (przy użyciu wyjścia pionowego):
@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
W Nowej Zelandii czas letni kończy się 5 marca 2020 r. Dlatego w tym przykładzie używam dwóch dat (1 marca i 7 marca).
Kiedy przekonwertuję je na „Nowy Zelandzki czas standardowy”, AT TIME ZONE
automatycznie uwzględnia w swoich obliczeniach czas letni i zwraca odpowiednią datę/godzinę.
Widzimy więc, że data 1 marca wykorzystuje przesunięcie strefy czasowej o +13:00, a data 7 marca wykorzystuje +12:00 (ponieważ czas letni zakończył się 5 marca).
Gdybym użył SWITCHOFFSET()
Musiałbym wiedzieć, jakiego przesunięcia strefy czasowej użyć dla każdej daty.
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];
Wynik (przy użyciu wyjścia pionowego):
@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
Konwersja z dat bez przesunięcia strefy czasowej
Możesz także użyć AT TIME ZONE
w datach bez przesunięcia strefy czasowej. W rzeczywistości funkcja akceptuje każde wyrażenie, które można rozwiązać na smalldatetime , data i godzina , datagodzina2 lub przesunięcie daty i godziny wartość.
Jednak kiedy to zrobisz, musisz pamiętać o tym, jak obliczany jest wynik. Gdy data jest podana bez informacji o przesunięciu, funkcja stosuje przesunięcie strefy czasowej, zakładając, że data wejściowa znajduje się w docelowej strefie czasowej.
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];
Wynik:
@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
Zauważ, że chociaż przesunięcia stref czasowych zostały zastosowane zgodnie z opisem, nie wpłynęło to na datę/godzinę. Obie wynikowe daty/czasy mają tę samą wartość – zmieniło się tylko przesunięcie strefy czasowej.
Jeśli nie tego chcesz, możesz dodać AT TIME ZONE 'UTC'
do miksu, aby najpierw przekonwertować oryginalne daty na UTC, zanim zostaną one przekonwertowane na żądaną strefę czasową.
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];
Wynik:
@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