Este artigo contém exemplos de conversão de um tempo valor para um datetime2 valor no SQL Server.
Quando você converte um tempo valor para datetime2 , informações extras são adicionadas ao valor. Isso ocorre porque o datetime2 tipo de dados contém informações de data e hora. A hora O tipo de dados, por outro lado, contém apenas informações de tempo.
Mais especificamente, a data é definida como '1900-01-01' (a menos que seja arredondada para '1900-01-02'), o componente de hora é copiado e, de acordo com a documentação da Microsoft, o deslocamento de fuso horário está definido para 00:00 (mesmo que o datetime2 tipo de dados não reconhece o fuso horário e não preserva nenhum deslocamento de fuso horário).
Quando a precisão de segundos fracionários de datetime2(n) o valor é maior que o tempo(n) valor, o valor é arredondado para cima.
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 datetime2 . DECLARE @thetime time;SET @thetime ='23:15:59.004007';SELECT @thetime AS 'time', CAST(@thetime AS datetime2) AS 'datetime2';
Resultado:
+------------------+--------------------------- --+| tempo | datetime2 ||------------------+---------------------------- -|| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |+------------------+------------------- ----------+
Quando você converte de tempo para datetime2 , um componente de data é adicionado e definido como
1900-01-01
. No entanto, há cenários em que a data pode ser arredondada para
1900-01-02
. Isso dependerá dos segundos fracionários e da precisão que você usar. Veja abaixo um exemplo disso. Exemplo 2 – Precisão de segundos fracionários
Você pode obter resultados diferentes dependendo da precisão de segundos fracionários atribuída a cada tipo de dados. Isso dependerá do valor real da parte fracionária.
No exemplo anterior, ambos os tipos de dados usaram a mesma precisão de segundos fracionários. Isso ocorre porque eu não especifiquei uma escala (para definir sua precisão) e, portanto, ambos usaram seus valores de escala padrão (ambos são 7).
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.
De qualquer forma, nesse exemplo atribuí apenas 6 casas decimais ao valor inicial, portanto, um zero é adicionado ao final.
Veja o que acontece se eu especificar uma precisão maior para o tempo valor comparado ao datetime2 valor:
DECLARE @thetime time(7);SET @thetime ='23:15:59.1234567';SELECT @thetime AS 'time', CAST(@thetime AS datetime2(4)) AS 'datetime2(4)';
Resultado:
+------------------+--------------------------+ | tempo | datetime2(4) ||------------------+---------------------------- -|| 23:15:59.1234567 | 1900-01-01 23:15:59.1235 |+------------------+------------------- -------+
Ao especificar uma escala de 4 para o datetime2 valor, o resultado é reduzido para 4 casas decimais, e neste caso é arredondado.
Como você pode esperar, não é apenas a parte fracionária que pode ser arredondada. Aqui está um exemplo de onde a parte fracionária faz com que os minutos e segundos sejam arredondados:
DECLARE @thetime time(7);SET @thetime ='23:15:59.7654321';SELECT @thetime AS 'time', CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';
Resultado:
+------------------+---------------------+| tempo | datetime2(0) ||------------------+---------------------|| 23:15:59.7654321 | 1900-01-01 23:16:00 |+------------------+------------------- --+
No entanto, você pode obter resultados diferentes para os mesmos dados alterando a precisão. Se aumentarmos a precisão, mesmo que seja apenas uma casa decimal, obteremos isso:
DECLARE @thetime time(7);SET @thetime ='23:15:59.7654321';SELECT @thetime AS 'time', CAST(@thetime AS datetime2(1)) AS 'datetime2(1)';
Resultado:
+------------------+-----------------------+| tempo | datetime2(1) ||------------------+-----------------------|| 23:15:59.7654321 | 1900-01-01 23:15:59.8 |+------------------+------------------- ----+
Então, neste caso, os minutos e segundos não foram arredondado para cima (mas milissegundos foram ).
Veja o que acontece se eu definir a hora valor para usar uma escala de precisão menor que o datetime2 valor.
DECLARE @thetime time(0);SET @thetime ='23:15:59.004007';SELECT @thetime AS 'time', CAST(@thetime AS datetime2) AS 'datetime2';
Resultado:
+----------+-----------------------------+| tempo | datetime2 ||----------+-----------------------------|| 23:15:59 | 1900-01-01 23:15:59.0000000 |+----------+------------------------------------------ --+
E enquanto estamos nisso, aqui está um exemplo de onde nossa escala de precisão pode resultar em segundos fracionários fazendo com que a data seja arredondada para o dia seguinte:
DECLARE @thetime time(7);SET @thetime ='23:59:59.9999999';SELECT @thetime AS 'time', CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';
Resultado:
+------------------+---------------------+| tempo | datetime2(0) ||------------------+---------------------|| 23:59:59.9999999 | 1900-01-02 00:00:00 |+------------------+------------------- --+Exemplo 3 – Conversão explícita usando CONVERT()
Este é o mesmo que o primeiro exemplo, exceto que desta vez eu uso oCONVERT()
função em vez deCAST()
.
DECLARE @thetime time;SET @thetime ='23:15:59.004007';SELECT @thetime AS 'time', CONVERT(datetime2, @thetime) AS 'datetime2';
Resultado:
+------------------+--------------------------- --+| tempo | datetime2 ||------------------+---------------------------- -|| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |+------------------+------------------- ----------+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, @thedatetime2 datetime2;SET @thetime ='23:15:59.004007';SET @thedatetime2 =@thetime;SELECT @thetime AS 'time', @thedatetime2 AS 'datetime2';
Resultado:
+------------------+--------------------------- --+| tempo | datetime2 ||------------------+---------------------------- -|| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |+------------------+------------------- ----------+
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 datetime2 variável.
Exemplo 5 – Alterar a data
Se você precisar alterar a data (mas manter a mesma hora), você pode usar oDATEADD()
função.
DECLARE @thetime time, @thedatetime2 datetime2;SET @thetime ='23:15:59.004007';SET @thedatetime2 =@thetime;SET @thedatetime2 =DATEADD(year, 120, @thedatetime2);SELECT @thetime AS ' hora', @thedatetime2 AS 'datetime2';
Resultado:
+------------------+--------------------------- --+| tempo | datetime2 ||------------------+---------------------------- -|| 23:15:59.0040070 | 01-01-2020 23:15:59.0040070 |+------------------+------------------- ----------+
Nesse caso, acrescento 120 ao valor do ano, o que o traz para 2020.