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

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


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

Quando você converte um tempo valor para datetimeoffset , a data é definida como '1900-01-01' e a hora é copiada. Um deslocamento de fuso horário é adicionado e definido como +00:00.


Exemplo 1 – 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 de tempo para deslocamento de data e hora .
DECLARE @thetime time;
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetimeoffset) AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.1234567 +00:00 |
+------------------+------------------------------------+

Assim, uma parte de data é adicionada e definida como '1900-01-01', a hora é copiada e um deslocamento de fuso horário é adicionado e definido como +00:00.

Exemplo 2 – Precisão


No exemplo anterior, ambos os tipos de dados usam sua precisão/escala padrão (7). Isso ocorre porque não adicionei uma escala entre colchetes (a escala determina a precisão dos segundos fracionários). Usando uma escala de 7, podemos ver que ambos os tipos de dados são capazes de representar um valor de tempo com precisão de 7 casas decimais.

Em outras palavras, quando eu inicialmente defino o @thetime variável, incluí 7 casas decimais no valor (especificamente, 1234567 ). Ambos os tipos de dados 'time' e 'datetimeoffset' foram capazes de representá-los com sucesso porque ambos usaram uma escala de 7. Novamente, sabemos que eles usaram 7 porque esse é o valor padrão.

Só para ficar claro, escala é o número de dígitos à direita do ponto decimal em um número. Precisão é o número total de dígitos no número.

Podemos reduzir a precisão dos segundos fracionários, se necessário.

Aqui estão alguns exemplos que demonstram o que acontece quando os tipos de dados são definidos para usar diferentes precisão de segundos fracionários:
DECLARE @thetime time(7);
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetimeoffset(0)) AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.0000000 +00:00 |
+------------------+------------------------------------+

Nesse caso, defino explicitamente o @thetime variável para usar uma escala de 7. Mas quando eu converto isso para datetimeoffset , defino a escala para 0. Portanto, o resultado para o datetimeoffset value é menos precisão de segundos fracionários. No meu sistema, 7 casas decimais ainda são exibidas, mas todas são 0.

Aqui está novamente, mas desta vez eu aumento a precisão de segundos fracionários para 3 para o datetimeoffset valor:
DECLARE @thetime time(7);
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetimeoffset(3)) AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.1230000 +00:00 |
+------------------+------------------------------------+

Portanto, ele usa os primeiros 3 segundos fracionários (milissegundos).

No entanto, se aumentarmos a precisão dos segundos fracionários para 4, veja o que acontece:
DECLARE @thetime time(7);
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetimeoffset(4)) AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.1235000 +00:00 |
+------------------+------------------------------------+

No próximo exemplo eu aumento o valor da parte fracionária para que ela cause a parte não fracionária do datetimeoffset valor a ser arredondado:
DECLARE @thetime time(7);
SET @thetime = '23:15:59.7654321';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetimeoffset(0)) AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.7654321 | 1900-01-01 23:16:00.0000000 +00:00 |
+------------------+------------------------------------+

Nesse caso, os minutos foram arredondados para cima e os segundos zerados.

Vamos trocá-lo para que o datetimeoffset tem uma precisão maior do que o tempo valor:
DECLARE @thetime time(4);
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetimeoffset(7)) AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1235000 | 1900-01-01 23:15:59.1235000 +00:00 |
+------------------+------------------------------------+

Eu declarei o @thetime variável para usar uma escala de 4, mas depois usou uma escala de 7 ao convertê-la para o datetimeoffset tipo de dados. Usar uma precisão de 7 é desnecessário, pois não pode usar uma precisão maior do que a que já foi atribuída.

Além disso, qualquer arredondamento de menor precisão já ocorreu no momento em que foi convertido para o (maior precisão) datetimeoffset tipo de dados. Observe que a hora tipo de dados arredondado os segundos fracionários para cima do valor inicial que atribuí a ele. Esse efeito de arredondamento também fluiu para o datetimeoffset valor.

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


Aqui está um exemplo usando o CONVERT() função em vez de CAST() .
DECLARE @thetime time;
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CONVERT(datetimeoffset, @thetime) AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.1234567 +00:00 |
+------------------+------------------------------------+

Exemplo 4 – Conversão implícita


Aqui está um exemplo de como fazer a mesma coisa, mas usando uma conversão de tipo implícita.
DECLARE @thetime time, @thedatetimeoffset datetimeoffset;
SET @thetime = '23:15:59.1234567';
SET @thedatetimeoffset = @thetime;
SELECT 
  @thetime AS 'time',
  @thedatetimeoffset AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.1234567 +00:00 |
+------------------+------------------------------------+

Assim, obtemos o mesmo resultado, independentemente de ser uma conversão explícita ou implícita.

Esta é uma conversão implícita porque não estamos usando uma função de conversão para convertê-la explicitamente. Estamos simplesmente atribuindo o valor de uma variável de um tipo de dados a uma variável de outro tipo de dados. Nesse caso, o SQL Server executa uma conversão implícita nos bastidores quando tentamos atribuir o tempo valor para um offset de data e hora variável.

Exemplo 5 – Alterar a data


Se você precisar alterar a data (mas manter a mesma hora), você pode usar o DATEADD() função.
DECLARE @thetime time, @thedatetimeoffset datetimeoffset;
SET @thetime = '23:15:59.1234567';
SET @thedatetimeoffset = @thetime;
SET @thedatetimeoffset = DATEADD(year, 285, @thedatetimeoffset);
SELECT 
  @thetime AS 'time',
  @thedatetimeoffset AS 'datetimeoffset';

Resultado:
+------------------+------------------------------------+
| time             | datetimeoffset                     |
|------------------+------------------------------------|
| 23:15:59.1234567 | 2185-01-01 23:15:59.1234567 +00:00 |
+------------------+------------------------------------+

Neste caso, acrescento 285 ao valor do ano, o que o leva a 2185.