ЧАСОВОЙ ПОЯС (Transact-SQL)

Применимо к: SQL Server 2016 (13.x) и более поздние версии:конечная точка аналитики SQL AzureSynapse Analytics в хранилище MicrosoftFabric в базе данных SQL Microsoft Fabric в Microsoft Fabric

Оператор AT TIME ZONE Transact-SQL (T-SQL) преобразует input_date в соответствующее значение datetimeoffset в целевом часовом поясе. Когда input_date предоставляется без информации о смещении, функция применяет смещение часового пояса, предполагая, что input_date находится в целевом часовом поясе.

Если input_date предоставлено как значение datetimeoffset , то AT TIME ZONE clause преобразует его в целевой часовой пояс с помощью правил преобразования часового пояса.

Реализация AT TIME ZONE основана на механизме Windows для преобразования значений дата-времени между часовыми поясами.

Соглашения о синтаксисе Transact-SQL

Syntax

input_date AT TIME ZONE time_zone_value
input_date AT TIME ZONE { 'time_zone_value' | 'LOCAL' }

Arguments

input_date

Выражение, которое можно разрешить в значение smalldatetime, datetime, datetime2 или datetimeoffset.

'time_zone_value'

Имя целевого часового пояса. time_zone_value — нварчар(128).

SQL Server использует часовые пояса, хранящиеся в реестре Windows. Часовые пояса, установленные на компьютере, хранятся в следующем кусте реестра: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

Список установленных часовых поясов также отображается через вид sys.time_zone_info системы.

Дополнительные сведения о часовых поясах для SQL Server в Linux см. в статье "Настройка часового пояса для SQL Server 2022 и более поздних версий в Linux".

{ 'time_zone_value' | 'МЕСТНЫЙ' }

Имя целевого часового пояса. time_zone_value — nvarchar(128), при условии по умолчанию .LOCAL

Список установленных часовых поясов отображается через вид sys.time_zone_info системы.

Если LOCAL указано, то текущее значение часового пояса по умолчанию для сессии устанавливается на исходное значение сессии, которое может быть либо опцией с ограничением базы данных, либо экземпляром по умолчанию.

Типы возвращаемых данных

Возвращает тип данных datetimeoffset.

Возвращаемое значение

Значение datetimeoffset в целевом часовом поясе.

Remarks

AT TIME ZONEПрименяет определенные правила для преобразования входных значений в типах данных smalldatetime, datetime и datetime2, которые попадают в интервал, затронутый изменением DST:

  • Если часы переводятся вперед, возникает разница с местным временем, равная интервалу перевода. Интервал обычно составляет 1 час, но в некоторых часовых поясах это может быть 30–45 минут. Точки во времени, попадающие в указанный период, преобразуются со смещением после перехода на летнее время.

    /*
      Moving to DST in "Central European Standard Time" zone:
      offset changes from +01:00 -> +02:00
      Change occurred on March 27th, 2022 at 02:00:00.
      Adjusted local time became 2022-03-27 03:00:00.
    */
    
    --Time before DST change has standard time offset (+01:00)
    SELECT CONVERT (DATETIME2 (0), '2022-03-27T01:01:00', 126)
        AT TIME ZONE 'Central European Standard Time';
    
    --Result: 2022-03-27 01:01:00 +01:00
    /*
      Adjusted time from the "gap interval" (between 02:00 and 03:00)
      is moved 1 hour ahead and presented with the summer time offset
      (after the DST change)
    */
    SELECT CONVERT (DATETIME2 (0), '2022-03-27T02:01:00', 126)
        AT TIME ZONE 'Central European Standard Time';
    
    --Result: 2022-03-27 03:01:00 +02:00
    
    --Time after 03:00 is presented with the summer time offset (+02:00)
    SELECT CONVERT (DATETIME2 (0), '2022-03-27T03:01:00', 126)
        AT TIME ZONE 'Central European Standard Time';
    
    --Result: 2022-03-27 03:01:00 +02:00
    
  • Если время переводится назад, 2 часа местного времени перекрываются на один час. В этом случае точки во времени, входящие в перекрывающийся интервал, представляются со смещением после изменения времени.

    /*
        Moving back from DST to standard time in
        "Central European Standard Time" zone:
        offset changes from +02:00 -> +01:00.
        Change occurred on October 30th, 2022 at 03:00:00.
        Adjusted local time became 2022-10-30 02:00:00
    */
    
    --Time before the change has DST offset (+02:00)
    SELECT CONVERT (DATETIME2 (0), '2022-10-30T01:01:00', 126)
        AT TIME ZONE 'Central European Standard Time';
    
    --Result: 2022-10-30 01:01:00 +02:00
    /*
      Time from the "overlapped interval" is presented with DST offset (before the change)
    */
    SELECT CONVERT (DATETIME2 (0), '2022-10-30T02:00:00', 126)
        AT TIME ZONE 'Central European Standard Time';
    
    --Result: 2022-10-30 02:00:00 +02:00
    
    --Time after 03:00 is regularly presented with the standard time offset (+01:00)
    SELECT CONVERT (DATETIME2 (0), '2022-10-30T03:01:00', 126)
        AT TIME ZONE 'Central European Standard Time';
    
    --Result: 2022-10-30 03:01:00 +01:00
    

Так как некоторые сведения (например, правила часового пояса) поддерживаются за пределами SQL Server и подвергаются случайным изменениям, AT TIME ZONE функция классируется как недетерминированная.

Хотя datetimeoffset не поддерживается в хранилище данных в Microsoft Fabric, AT TIME ZONE можно по-прежнему использовать с datetime2, как показано в следующем примере.

Examples

A. Добавление смещения часового пояса к datetime без сведений о смещении

Используйте AT TIME ZONE для добавления смещения на основе правил часового пояса, когда вы знаете, что исходные значения даты и времени предоставляются в одном часовом поясе:

USE AdventureWorks2025;
GO

SELECT SalesOrderID,
       OrderDate,
       OrderDate AT TIME ZONE 'Pacific Standard Time' AS OrderDate_TimeZonePST
FROM Sales.SalesOrderHeader;

Вот результат.

SalesOrderID OrderDate               OrderDate_TimeZonePST
------------ ----------------------- -------------------------------
43659        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00
43660        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00
43661        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00
43662        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00
43663        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00
43664        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00
...

B. Преобразование значений между разными часовыми поясами

В следующем примере выполняется преобразование значений из одного часового пояса в другой. Значения OrderDate — datetime и не хранятся со смещением, но известны как тихоокеанское стандартное время. В первую очередь необходимо назначить известное смещение и выполнить преобразование в новый часовой пояс:

USE AdventureWorks2025;
GO

SELECT SalesOrderID,
       OrderDate,
       --Assign the known offset only
       OrderDate AT TIME ZONE 'Pacific Standard Time' AS OrderDate_TimeZonePST,
       --Assign the known offset, then convert to another time zone
       OrderDate AT TIME ZONE 'Pacific Standard Time' AT TIME ZONE 'Central European Standard Time' AS OrderDate_TimeZoneCET
FROM Sales.SalesOrderHeader;

Вот результат.

SalesOrderID OrderDate               OrderDate_TimeZonePST          OrderDate_TimeZoneCET
------------ ----------------------- ------------------------------ -------------------------------
43659        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43660        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43661        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43662        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43663        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43664        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
...

Вы также можете заменить локальную переменную, содержащую часовой пояс:

USE AdventureWorks2025;
GO

DECLARE @CustomerTimeZone AS NVARCHAR (128) = 'Central European Standard Time';

SELECT SalesOrderID,
       OrderDate,
       --Assign the known offset only
       OrderDate AT TIME ZONE 'Pacific Standard Time' AS OrderDate_TimeZonePST,
       --Assign the known offset, then convert to another time zone
       OrderDate AT TIME ZONE 'Pacific Standard Time' AT TIME ZONE @CustomerTimeZone AS OrderDate_TimeZoneCustomer
FROM Sales.SalesOrderHeader;

Вот результат.

SalesOrderID OrderDate               OrderDate_TimeZonePST          OrderDate_TimeZoneCustomer
------------ ----------------------- ------------------------------ -------------------------------
43659        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43660        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43661        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43662        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43663        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
43664        2022-05-30 00:00:00.000 2022-05-30 00:00:00.000 -07:00 2022-05-30 09:00:00.000 +02:00
...

C. Запрос темпоральных таблиц с помощью определенного часового пояса

Следующий пример выбирает данные из временной таблицы с WideWorldImporters использованием Тихоокеанского стандартного времени.

USE WideWorldImporters;
GO

DECLARE @ASOF AS DATETIMEOFFSET;
SET @ASOF = DATEADD(MONTH, -1, GETDATE()) AT TIME ZONE 'UTC';

-- Query state of the table a month ago projecting period
-- columns as Pacific Standard Time
SELECT CustomerID,
       CustomerName,
       ValidFrom AT TIME ZONE 'Pacific Standard Time'
FROM Sales.Customers FOR SYSTEM_TIME AS OF @ASOF;

Вот результат.

CustomerID CustomerName                        ValidFrom
---------- ----------------------------------- ----------------------------------
1          Tailspin Toys (Head Office)         2013-01-01 00:00:00.0000000 -08:00
2          Tailspin Toys (Sylvanite, MT)       2013-01-01 00:00:00.0000000 -08:00
3          Tailspin Toys (Peeples Valley, AZ)  2013-01-01 00:00:00.0000000 -08:00
4          Tailspin Toys (Medicine Lodge, KS)  2013-01-01 00:00:00.0000000 -08:00
5          Tailspin Toys (Gasport, NY)         2013-01-01 00:00:00.0000000 -08:00
6          Tailspin Toys (Jessie, ND)          2013-01-01 00:00:00.0000000 -08:00