時區 (Transact-SQL)

適用於: SQL Server 2016 (13.x) 及以後版本 Azure SQL Database AzureSQL Managed InstanceAzure Synapse AnalyticsSQL Analytics endpoint in Microsoft FabricWarehouse in Microsoft FabricSQL database in 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是nvarchar(128)。

SQL Server 依賴儲存在 Windows 登錄中的時區。 安裝於電腦上的時區均儲存於下列登錄區中:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones。

sys.time_zone_info系統檢視也會顯示已安裝的時區清單。

如需 Linux 上 SQL Server 時區的詳細資訊,請參閱 在 Linux 上設定 SQL Server 2022 和更新版本的時區。

{ '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 分鐘,視時區而定。 將會使用在 DST 變更「後」之位移來轉換位於此落差中的時間點。

    /*
      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 個小時的本地時間就會重疊成 1 個小時。 在此情況下,會使用在時鐘變更「之前」的位移來顯示屬於重疊間隔的時間點:

    /*
        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 函數會被歸類為不具決定性的函數。

雖然 Microsoft Fabric 中的數據倉儲不支援 datetimeoffset,AT TIME ZONE但仍可與 datetime2 搭配使用,如下列範例所示。

Examples

A. 將目標時區位移新增至不含位移資訊的日期時間

當您知道在相同時區中已提供原始 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