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

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


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

Ao converter um datetime2 valor para datetimeoffset , o valor resultante dependerá da precisão de segundos fracionários atribuída a cada tipo de dados, bem como de qualquer deslocamento de fuso horário que você especificar.

Ambos os tipos de dados permitem especificar uma precisão de segundos fracionários de 0 a 7. Se você não especificar isso, a escala padrão de 7 será usada.

O deslocamento de data e hora tipo de dados inclui um deslocamento de fuso horário e pode preservar quaisquer deslocamentos no valor original. No entanto, datetime2 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 TODATETIMEOFFSET() função foi projetada especificamente para converter um valor de data/hora para datetimeoffset e adicione um deslocamento de fuso horário. No entanto, veja meus comentários (e exemplos) abaixo sobre essa opção.


Exemplo 1 – Conversão implícita


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

Resultado:
+-----------------------------+------------------------------------+
| datetime2                   | datetimeoffset(7)                  |
|-----------------------------+------------------------------------|
| 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.1234567 +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 datetime2 valor para um offset de data e hora variável.

Podemos ver que o datetimeoffset variável é capaz de usar a mesma precisão que a datetime2 valor (7 casas decimais). 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 11 bytes para armazenamento (10 para os dados e 1 byte para a precisão). O datetime2 type usa 9 bytes (8 para os dados e 1 byte para a precisão) ao usar uma escala de 7.

No entanto, você pode reduzir a precisão substituindo o 7 por um número menor.

Exemplo 2 – Arredondamento


Se deslocamento de data e hora tem uma precisão menor que o datetime2 valor, será arredondado para cima.

Aqui está um exemplo:
DECLARE 
  @thedatetime2 datetime2(7), 
  @thedatetimeoffset datetimeoffset(6);
SET @thedatetime2 = '2025-05-21 10:15:30.1234567';
SET @thedatetimeoffset = @thedatetime2;
SELECT 
  @thedatetime2 AS 'datetime2(7)',
  @thedatetimeoffset AS 'datetimeoffset(6)';

Resultado:
+-----------------------------+------------------------------------+
| datetime2(7)                | datetimeoffset(6)                  |
|-----------------------------+------------------------------------|
| 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.1234570 +00:00 |
+-----------------------------+------------------------------------+

Neste exemplo, o datetime2 valor tem uma escala de 7, mas o datetimeoffset a escala do valor é de apenas 6. Portanto, sua precisão é de apenas 6 casas decimais e seu sexto dígito é arredondado para 7 (em vez de 6).

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 datetime2 e deslocamento de data e hora .
DECLARE @thedatetime2 datetime2;
SET @thedatetime2 = '2025-05-21 10:15:30.1234567';
SELECT 
  @thedatetime2 AS 'datetime2',
  CAST(@thedatetime2 AS datetimeoffset) AS 'datetimeoffset';

Resultado:
+-----------------------------+------------------------------------+
| datetime2                   | datetimeoffset                     |
|-----------------------------+------------------------------------|
| 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.1234567 +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 @thedatetime2 datetime2;
SET @thedatetime2 = '2025-05-21 10:15:30.1234567';
SELECT 
  @thedatetime2 AS 'datetime2',
  CONVERT(datetimeoffset, @thedatetime2) AS 'datetimeoffset';

Resultado:
+-----------------------------+------------------------------------+
| datetime2                   | datetimeoffset                     |
|-----------------------------+------------------------------------|
| 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.1234567 +00:00 |
+-----------------------------+------------------------------------+

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


Se você estiver convertendo de datetime2 para deslocamento de data e hora , você provavelmente está fazendo isso para o deslocamento do fuso horário. Também é muito provável que você precise de um valor diferente do padrão +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 original datetime2 valor para um offset de data e hora valor. Esta função aceita qualquer valor de data/hora que possa ser resolvido para um datetime2 valor e um valor de deslocamento.

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

Resultado:
+-----------------------------+------------------------------------+
| datetime2                   | datetimeoffset                     |
|-----------------------------+------------------------------------|
| 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.1234567 +07:00 |
+-----------------------------+------------------------------------+

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

Resultado:
+-----------------------------+------------------------------------+
| datetime2                   | datetimeoffset                     |
|-----------------------------+------------------------------------|
| 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.1234567 +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.

Portanto, se seu datetime2 usa uma precisão menor do que o datetimeoffset , você sempre pode reatribuí-lo a uma variável com maior precisão e, em seguida, passar esse valor convertido para TODATETIMEOFFSET() .

Exemplo:
DECLARE @lowprecision datetime2(3), @highprecision datetime2(7);
SET @lowprecision = '2025-05-21 10:15:30.123';
SET @highprecision = @lowprecision;
SELECT 
  @lowprecision AS 'lowprecision',
  @highprecision AS 'highprecision',
  TODATETIMEOFFSET(@highprecision, '+07:00') AS 'Modified';

Resultado (usando saída vertical):
lowprecision  | 2025-05-21 10:15:30.123
highprecision | 2025-05-21 10:15:30.1230000
Modified      | 2025-05-21 10:15:30.1230000 +07:00