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

Converter 'smalldatetime' para 'datetimeoffset' no SQL Server (Exemplos de T-SQL)


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

Quando você converte uma pequena data e hora valor para datetimeoffset , o pequeno tempo de data o valor é copiado para o datetimeoffset valor. Os segundos fracionários são definidos como 0 e o deslocamento de fuso horário é definido como +00:0.



A pequena data e hora tipo de dados não possui segundos fracionários e seu componente de segundos é sempre definido como zero (:00). Sua precisão é para o minuto mais próximo.

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, smalldatetime não tem reconhecimento de fuso horário, portanto, não há valores existentes a serem preservados. Nesse caso, o deslocamento do fuso horário é definido como +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, veja abaixo meus comentários e alguns exemplos sobre essa opção.

Exemplo 1 – Conversão implícita


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

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

Podemos ver que o datetimeoffset variável tem uma parte fracionária ( 0000000 ), enquanto o smalldatetime valor não possui parte fracionária, e seus minutos foram arredondados para cima ao atribuir o valor inicial a ele. O deslocamento de data e hora value também inclui 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 bytes para armazenar os dados, 1 byte para a precisão). Em comparação, smalldatetime usa apenas 4 bytes. No entanto, você pode reduzir a precisão do datetimeoffset valor substituindo o 7 por um número menor. Se você deseja remover completamente a parte dos segundos fracionários, basta usar datetimeoffset(0) . Isso reduzirá o tamanho do armazenamento para 9 bytes (incluindo 1 para a precisão).

Exemplo 2 – 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 para converter explicitamente entre smalldatetime e deslocamento de data e hora .
DECLARE @thesmalldatetime smalldatetime;
SET @thesmalldatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  CAST(@thesmalldatetime AS datetimeoffset(7)) AS 'datetimeoffset(7)';

Resultado:
+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset(7)                  |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +00:00 |
+---------------------+------------------------------------+

Exemplo 3 – 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 @thesmalldatetime smalldatetime;
SET @thesmalldatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  CONVERT(datetimeoffset(7), @thesmalldatetime) AS 'datetimeoffset(7)';

Resultado:
+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset(7)                  |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +00:00 |
+---------------------+------------------------------------+

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


O fato de você estar convertendo seu smalldatetime valores para datetimeoffset significa que você provavelmente está fazendo isso para o deslocamento do fuso horário. E é provável que você queira definir um deslocamento diferente de +00:00 (o deslocamento padrão).

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

Você também pode usar esta função para converter o smalldatetime 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 @thesmalldatetime smalldatetime, @thedatetimeoffset datetimeoffset;
SET @thesmalldatetime = '2025-05-21 10:15:30';
SET @thedatetimeoffset = TODATETIMEOFFSET(@thesmalldatetime, '+07:00');
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  @thedatetimeoffset AS 'datetimeoffset';

Resultado:
+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset                     |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +07:00 |
+---------------------+------------------------------------+

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

Resultado:
+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset                     |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +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 pequeno tempo de data argumento, que não tem segundos fracionários.

Meu sistema retorna zeros à direita com datetimeoffset parte fracionária, no entanto, você pode ver algo assim:
+---------------------+----------------------------+
| smalldatetime       | datetimeoffset             |
|---------------------+----------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00 +07:00 |
+---------------------+----------------------------+

De qualquer forma, você ainda pode aproveitar ao máximo o datetimeoffset precisão do tipo de dados se você precisar modificar o valor posteriormente.

Aqui está um exemplo que usa o DATEADD() função para alterar os segundos fracionários após a conversão já ter sido feita.
DECLARE @thesmalldatetime smalldatetime, @thedatetimeoffset datetimeoffset(7);
SET @thesmalldatetime = '2025-05-21 10:15:30';
SET @thedatetimeoffset = TODATETIMEOFFSET(@thesmalldatetime, '+07:00');
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  @thedatetimeoffset AS 'datetimeoffset',
  DATEADD(nanosecond, 123456700, @thedatetimeoffset) AS 'Modified';

Resultado (usando saída vertical):
smalldatetime  | 2025-05-21 10:16:00
datetimeoffset | 2025-05-21 10:16:00.0000000 +07:00
Modified       | 2025-05-21 10:16:00.1234567 +07:00