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