Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Converter 'datetime' em 'datetimeoffset' no SQL Server (Exemplos de T-SQL)


Este artigo contém exemplos de conversão de um datetime valor para um offset de data e hora valor no SQL Server.

Ao converter um datetime valor para datetimeoffset , o valor resultante dependerá da precisão de segundos fracionários que você atribuir a datetimeoffset , bem como qualquer deslocamento de fuso horário que você especificar.

O datahora tipo de dados tem um máximo de 3 dígitos para sua parte de segundos fracionários. Sua precisão é arredondada para incrementos de 0,000, 0,003 ou 0,007 segundos.

O deslocamento de data e hora O tipo de dados, por outro lado, permite especificar uma precisão de segundos fracionários de 0 a 7. Se você não especificar isso, usará 7 (o padrão). Ele também tem um deslocamento de fuso horário e pode preservar quaisquer deslocamentos no valor original. No entanto, datahora não tem reconhecimento de fuso horário, portanto, não há valores existentes a serem preservados. Nesse caso, o deslocamento de fuso horário é padronizado para +00:00.

O SQL Server realmente tem o TODATETIMEOFFSET() função, que é projetada especificamente para converter um valor de data/hora em datetimeoffset e adicione um deslocamento de fuso horário. No entanto, há um detalhe sutil a ser observado ao usar essa função, e explico isso abaixo (com exemplos).


Exemplo 1 – Conversão implícita


Primeiro, aqui está um exemplo de uma conversão implícita entre datetime e deslocamento de data e hora .
DECLARE 
  @thedatetime datetime, 
  @thedatetimeoffset datetimeoffset(7);
SET @thedatetime = '2025-05-21 10:15:30.123';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset(7)';

Resultado:
+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.123 | 2025-05-21 10:15:30.1233333 +00:00 |
+-------------------------+------------------------------------+

Esta é uma conversão implícita porque não estamos usando uma função de conversão (como as abaixo) para convertê-la explicitamente. Nesse caso, o SQL Server executa uma conversão implícita nos bastidores quando tentamos atribuir o datetime valor para um offset de data e hora variável.

Podemos ver que o datetimeoffset variável tem mais precisão de segundos fracionários, e acabamos com uma parte fracionária de 1233333 (vs 123 para o datahora valor). Também acabamos com um deslocamento de fuso horário de +00:00 .

Usar a precisão de 7 segundos fracionários causa datetimeoffset usar 10 bytes para armazenamento (11 bytes se você incluir o byte que armazena sua precisão). A título de comparação, datetime usa apenas 8 bytes. No entanto, você pode reduzir a precisão do datetimeoffset valor substituindo o 7 por um número menor. Este é o mesmo conceito de usar o datetime2 tipo de dados. Consulte Converter 'datetime' em 'datetime2' no SQL Server para obter exemplos de como isso pode afetar o resultado final.

Exemplo 2 – Arredondamento


O datahora tipo de dados é arredondado para incrementos de 0,000, 0,003 ou 0,007 segundos. Mesmo que você o defina explicitamente para outro valor, ele será arredondado. Isso pode causar muita confusão se você não estiver ciente de como funciona. Não só pode causar confusão ao usar datetime por si só, pode causar confusão extra ao converter esse valor para outro tipo de dados.

Aqui está um exemplo que demonstra o que quero dizer.
DECLARE 
  @thedatetime datetime, 
  @thedatetimeoffset datetimeoffset;
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset(7)';

Resultado:
+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

Neste exemplo, defino os segundos fracionários para 125 mas datahora arredondado para 127 (porque esse tipo de dados só pode ser arredondado para incrementos de 0,000, 0,003 ou 0,007 segundos).

O deslocamento de data e hora por outro lado, defina os segundos fracionários para 1266667 .

No entanto, se simplesmente definirmos o valor inicial como datetimeoffset em primeiro lugar, sua parte fracionária teria retornado 1250000 .

Exemplo 3 – Conversão explícita usando CAST()


Aqui está um exemplo de uma conversão explícita. Neste caso, eu uso o CAST() função diretamente dentro do SELECT instrução para converter explicitamente entre datetime e deslocamento de data e hora .
DECLARE @thedatetime datetime;
SET @thedatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  CAST(@thedatetime AS datetimeoffset(7)) AS 'datetimeoffset(7)';

Resultado:
+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

Exemplo 4 – Conversão explícita usando CONVERT()


Aqui está um exemplo de uma conversão explícita usando o CONVERT() função em vez de CAST() .
DECLARE @thedatetime datetime;
SET @thedatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  CONVERT(datetimeoffset(7), @thedatetime) AS 'datetimeoffset(7)';

Resultado:
+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

Exemplo 5 – Alteração do deslocamento de fuso horário


Se você estiver tendo todo o trabalho de converter seu datetime valores para datetimeoffset , você provavelmente precisará do deslocamento de fuso horário. E há uma forte possibilidade de que você queira definir algo diferente de +00:00.

Felizmente, você pode usar o TODATETIMEOFFSET() função para alterar o deslocamento.

Você também pode usar esta função para converter o datetime original valor para um offset de data e hora valor. Esta função aceita um valor de data/hora (que pode resolver para um datetime2 valor) e um valor de deslocamento.

Aqui está um exemplo:
DECLARE @thedatetime datetime, @thedatetimeoffset datetimeoffset;
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = TODATETIMEOFFSET(@thedatetime, '+07:00');
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset';

Resultado:
+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1270000 +07:00 |
+-------------------------+------------------------------------+

E aqui está um exemplo usando a função dentro do SELECT demonstração:
DECLARE @thedatetime datetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  TODATETIMEOFFSET(@thedatetime, '+07:00') AS 'datetimeoffset';

Resultado:
+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1270000 +07:00 |
+-------------------------+------------------------------------+

Um ponto importante sobre o TODATETIMEOFFSET() função é que ela usa a mesma precisão fracionária que o argumento de data/hora passado para ela. Nesse caso, é um datetime argumento, por isso tem uma escala de 3 (ou seja, 3 segundos fracionários). Isso pode ou não ser um problema para você. Se for, você sempre poderá convertê-lo em um datetimeoffset primeiro, passe esse valor convertido para TODATETIMEOFFSET() .

Exemplo:
DECLARE @thedatetime datetime, @thedatetimeoffset datetimeoffset(7);
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset',
  TODATETIMEOFFSET(@thedatetimeoffset, '+07:00') AS 'Modified';

Resultado (usando saída vertical):
datetime       | 2025-05-21 10:15:30.127
datetimeoffset | 2025-05-21 10:15:30.1266667 +00:00
Modified       | 2025-05-21 10:15:30.1266667 +07:00