Provavelmente, há muito poucos casos de uso que fariam com que você convertesse um datetime2 valor para datetime no SQL Server. Em particular, o datetime2 tipo de dados pode ser definido para usar o mesmo tamanho de armazenamento que datetime , mas com maior precisão. Então, na maioria dos casos, seria melhor usar datetime2 do que com um datetime . A Microsoft também recomenda o uso de datetime2 em vez de datahora .
No entanto, caso você se encontre na situação em que precise realizar essa conversão, este artigo contém alguns exemplos e considerações que podem ser úteis.
Ao converter um datetime2 valor para datetime , o valor resultante dependerá dos segundos fracionários que foram atribuídos ao datetime2 valor, bem como a sua precisão.
O datetime2 tipo de dados permite que você especifique uma precisão de segundos fracionários de 0 a 7. Se você não especificar isso, ele usará 7 (o padrão).
O datahora o tipo de dados, por outro lado, tem no máximo 3 dígitos para sua parte de segundos fracionários. Sua precisão é arredondada para incrementos de 0,000, 0,003 ou 0,007 segundos.
Portanto, se o datetime2 usa uma escala de 3, o valor resultante será muito próximo (se não idêntico) ao valor original. No entanto, devido à menor precisão de datetime , os resultados podem ser diferentes, devido ao arredondamento que realiza.
Exemplo 1 – Conversão implícita
Aqui está um exemplo de uma conversão implícita entre datetime2 e datahora .
DECLARE @thedatetime2 datetime2, @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.1234567'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Resultado:
+-----------------------------+-------------------------+ | datetime2 | datetime | |-----------------------------+-------------------------| | 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.123 | +-----------------------------+-------------------------+
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 datetime variável.
Podemos ver que o datetime variável tem menos precisão de segundos fracionários, e acabamos com uma parte fracionária de 123 mesmo que a parte fracionária original fosse 1234567 .
Neste caso, nenhum arredondamento foi realizado.
Exemplo 2 – Precisão/exatidão e arredondamento
O datahora tipo de dados é arredondado para incrementos de 0,000, 0,003 ou 0,007 segundos. Mesmo que você o defina explicitamente para outro valor, ele será arredondado.
Isso também se aplica ao converter de outro tipo de dados (como o que estamos fazendo aqui).
Aqui está um exemplo que demonstra o que quero dizer.
DECLARE @thedatetime2 datetime2, @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.1256789'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Resultado:
+-----------------------------+-------------------------+ | datetime2 | datetime | |-----------------------------+-------------------------| | 2025-05-21 10:15:30.1256789 | 2025-05-21 10:15:30.127 | +-----------------------------+-------------------------+
Neste exemplo, defini os segundos fracionários do datetime2 valor para
1256789
mas datahora arredondado para
127
(porque só pode ser arredondado para incrementos de 0,000, 0,003 ou 0,007 segundos). É importante observar que isso ainda será verdade, mesmo se atribuirmos apenas 3 segundos fracionários ao datetime2 valor.
Exemplo:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.125'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Resultado:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.125 | 2025-05-21 10:15:30.127 | +-------------------------+-------------------------+
Também vale a pena estar ciente de qualquer arredondamento que possa ocorrer no datetime2 original valor. O datetime2 value pode ser arredondado para cima se tentarmos atribuir um valor com mais segundos fracionários do que sua própria escala.
Exemplo:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.1256789'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
Resultado:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.126 | 2025-05-21 10:15:30.127 | +-------------------------+-------------------------+
Nesse caso, tento atribuir um valor com uma parte fracionária de 1256789 . No entanto, como o datetime2(3) value tem apenas uma escala de 3, só pode suportar 3 casas decimais e, neste caso, o último dígito é arredondado (porque o dígito seguinte é 5 ou superior).
Ambos datetime2(3) e datahora use a mesma quantidade de espaço de armazenamento (8 bytes). O datetime2(3) tipo de dados na verdade usa 7 bytes para armazenar os dados, mas 1 byte extra para armazenar a precisão.
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 datahora . DECLARE @thedatetime2 datetime2; SET @thedatetime2 = '2025-05-21 10:15:30.1234567'; SELECT @thedatetime2 AS 'datetime2', CAST(@thedatetime2 AS datetime) AS 'datetime';
Resultado:
+-----------------------------+-------------------------+ | datetime2 | datetime | |-----------------------------+-------------------------| | 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.123 | +-----------------------------+-------------------------+
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(datetime, @thedatetime2) AS 'datetime';
Resultado:
+-----------------------------+-------------------------+ | datetime2 | datetime | |-----------------------------+-------------------------| | 2025-05-21 10:15:30.1234567 | 2025-05-21 10:15:30.123 | +-----------------------------+-------------------------+