O
AT TIME ZONE
cláusula foi introduzida no SQL Server 2016 para converter uma data em um datetimeoffset valor em um fuso horário de destino. Esta função é semelhante a algumas outras funções T-SQL, como
SWITCHOFFSET()
e TODATETIMEOFFSET()
, no entanto, o AT TIME ZONE
A cláusula permite/(requer) que você especifique o deslocamento de fuso horário por nome, em vez de um valor de deslocamento real. Este artigo explora como
AT TIME ZONE
funciona, e explica seus benefícios em relação às outras funções mencionadas. Exemplo de uso
Aqui está um exemplo básico de como o
AT TIME ZONE
cláusula funciona. 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];
Resultado (usando saída vertical):
Original | 2020-04-01 00:00:00.0000000 +00:00 NZ Time | 2020-04-01 13:00:00.0000000 +13:00
Você pode estar se perguntando por que a Microsoft introduziu esse recurso quando você poderia ter usado o
SWITCHOFFSET()
função para fazer a mesma coisa? Bem, você não pode na verdade, faça exatamente a mesma coisa com
SWITCHOFFSET()
. Com
SWITCHOFFSET()
, você deve fornecer o deslocamento de fuso horário real no formato [+|-]TZH:TZM ou como um inteiro com sinal (para minutos). Isso significa que você precisa saber o deslocamento exato do fuso horário, e se esse fuso horário está ou não observando o horário de verão. Com o
AT TIME ZONE
cláusula, você não precisa saber disso. Tudo o que você precisa saber é o nome do fuso horário (e veja como obter o nome do fuso horário). Exemplo de horário de verão
Aqui está um exemplo que demonstra o benefício de usar
AT TIME ZONE
no que diz respeito ao horário de verão. 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];
Resultado (usando saída vertical):
@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
Na Nova Zelândia, o horário de verão termina em 5 de março de 2020. Portanto, neste exemplo, uso duas datas (1 de março e 7 de março).
Quando eu os converto para 'Horário padrão da Nova Zelândia',
AT TIME ZONE
inclui automaticamente o horário de verão em seu cálculo e retorna a data/hora aplicável. Assim, podemos ver que a data de 1º de março usa um deslocamento de fuso horário de +13:00 e a data de 7 de março usa +12:00 (porque o horário de verão terminou em 5 de março).
Se eu tivesse usado
SWITCHOFFSET()
Eu teria que saber qual deslocamento de fuso horário usar para cada data. 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];
Resultado (usando saída vertical):
@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
Conversão de datas sem deslocamento de fuso horário
Você também pode usar
AT TIME ZONE
em datas sem deslocamento de fuso horário. Na verdade, a função aceita qualquer expressão que possa ser resolvida para um smalldatetime , datahora , datahora2 , ou deslocamento de data e hora valor. No entanto, ao fazer isso, você precisa estar atento a como o resultado é calculado. Quando a data é fornecida sem informações de deslocamento, a função aplica o deslocamento do fuso horário assumindo que a data de entrada está no fuso horário de destino.
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];
Resultado:
@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
Observe que, embora os deslocamentos de fuso horário tenham sido aplicados conforme especificado, isso não afetou a data/hora. Ambas as datas/horas resultantes têm o mesmo valor – apenas o deslocamento do fuso horário foi alterado.
Se isso não é o que você deseja, você pode adicionar
AT TIME ZONE 'UTC'
ao mix para primeiro converter as datas originais para UTC, antes de serem convertidas para o fuso horário desejado. 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];
Resultado:
@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