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

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


Se você tiver um deslocamento de data e hora valor, mas você não precisa da parte de deslocamento de data e fuso horário, convertendo-a em hora economizará muito espaço de armazenamento (ao remover detalhes desnecessários do valor). Este artigo contém exemplos de conversão de um datetimeoffset valor para um tempo valor no SQL Server.



O deslocamento de data e hora tipo de dados inclui a data e hora com um deslocamento de fuso horário. Ele também tem uma parte de segundos fracionários entre 0 e 7 (isso depende de quantos segundos fracionários são atribuídos a ele). Isso é feito usando o datetimeoffset(n) sintaxe. Se você não especificar isso, ele usará 7 (o padrão). O tamanho de armazenamento desse tipo de dados é de 8, 9 ou 10 bytes, dependendo da precisão que está sendo usada. Sua precisão é de 100 nanossegundos.

A hora tipo de dados, por outro lado, inclui apenas a hora. Não inclui a data e não inclui o deslocamento do fuso horário. No entanto, semelhante a datetimeoffset ele também permite que você especifique uma parte de segundos fracionários entre 0 e 7 (usando o time(n) sintaxe). Ele usa 3, 4 ou 5 bytes, dependendo de sua precisão.

Ao converter um offset de data e hora valor para um tempo tipo de dados, você perde a parte da data. Você também perde o deslocamento de fuso horário. No entanto, você também reduz o tamanho do armazenamento de 8 a 10 bytes para 3, 4 ou 5 bytes. No entanto, você só faria essa conversão se não precisasse da parte da data ou do deslocamento do fuso horário.

Observe que os valores de armazenamento listados aqui são os valores listados na documentação da Microsoft. No entanto, esses tipos de dados também usam 1 byte para armazenar a precisão. Portanto, você precisará adicionar 1 byte aos valores listados aqui.

Exemplo 1 – Conversão implícita


Aqui está um exemplo de uma conversão implícita entre datetimeoffset e tempo .
DECLARE 
  @thedatetimeoffset datetimeoffset, 
  @thetime time;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultado:
+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

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 datetimeoffset valor para um tempo variável.

Aqui podemos ver que o tempo valor inclui apenas a hora (sem o componente de data). Os componentes de deslocamento de data e fuso horário foram removidos do valor.

Neste exemplo, ambos os tipos de dados usam a precisão padrão (que resulta em 7 casas decimais). Isso resulta no deslocamento de data e hora valor usando 10 bytes e o tempo valor usando 5 bytes.

Exemplo 2 – Precisão


O resultado exato dependerá das configurações de precisão para cada tipo de dados. No próximo exemplo, o tempo value usa uma precisão menor para o original datetimeoffset valor:
DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultado:
+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1230000 |
+------------------------------------+------------------+

Meu sistema exibe zeros à direita, mas o ponto é que o tempo value agora tem uma precisão de apenas 3 casas decimais em comparação com as 7 casas decimais que o valor original usa.

Reduzir a precisão também pode resultar em tempo valor sendo arredondado. Aqui está um exemplo:
DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1235555 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultado:
+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1240000 |
+------------------------------------+------------------+

Nesse caso, acabamos com uma parte fracionária de 124 em vez de 123 , porque o dígito a seguir era 5 ou maior.

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 para converter explicitamente entre datetimeoffset e tempo .
DECLARE @thedatetimeoffset datetimeoffset;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  CAST(@thedatetimeoffset AS time) AS 'time'; 

Resultado:
+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

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

Resultado:
+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+