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.