Estou fazendo algumas consultas de seleção SQL e gostaria de converter minha coluna de data e hora UTC em horário local para ser exibida como horário local nos resultados da minha consulta. Observe que NÃO pretendo fazer essa conversão via código, mas quando estou fazendo consultas SQL manuais e aleatórias nos meus bancos de dados.
sql
sql-server
Nugs
fonte
fonte
Respostas:
Você pode fazer isso da seguinte maneira no SQL Server 2008 ou superior:
Você também pode fazer o menos detalhado:
Faça o que fizer, não use
-
para subtrair datas, porque a operação não é atômica, e você vai de vez em quando obter resultados indeterminados devido a condições de corrida entre a data e hora do sistema ea data e hora local, sendo verificado em momentos diferentes (isto é, não-atomicamente) .Observe que esta resposta não leva em consideração o horário de verão. Se você deseja incluir um ajuste de horário de verão, consulte também a seguinte pergunta do SO:
Como criar a função de Início e Fim do Horário de Verão no SQL Server
fonte
Não achei nenhum exemplo útil para obter um horário datado como UTC para um horário especificado em um fuso horário especificado (NÃO o fuso horário do servidor porque os bancos de dados SQL do Azure são executados como UTC). É assim que eu lidei com isso. Não é elegante, mas é simples e fornece a resposta certa sem manter outras tabelas:
fonte
AT TIME ZONE
sintaxe, considere stackoverflow.com/a/44941536/112764 - você pode encadear várias conversões juntas, simplesmente concatenando váriosat time zone <blah>
s.dateTimeField AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'
- apenas encadeando asAT TIME ZONE
instruções. (@NateJ mencionou isso acima, agora)Se a hora local da data for informada
Eastern Standard Time
e você desejar converter do UTC para isso, no Azure SQL e SQL Server 2016 e superior, você poderá:A lista completa de nomes de fuso horário pode ser encontrada em:
E sim, os fusos horários são mal nomeados - mesmo sendo
Eastern Standard Time
, o horário de verão é levado em consideração.fonte
Se você precisar de uma conversão diferente da localização do seu servidor, aqui está uma função que permite passar um deslocamento padrão e contabilizar o horário de verão americano:
fonte
Usando novas oportunidades do SQL Server 2016:
Mas o procedimento clr funciona 5 vezes mais rápido: '- (
Observe que o deslocamento de um fuso horário pode mudar para o inverno ou o verão. Por exemplo
resultados:
Você não pode simplesmente adicionar deslocamento constante.
fonte
Se ativar o CLR no seu banco de dados for uma opção e também usar o fuso horário do servidor sql, ele poderá ser gravado no .Net com bastante facilidade.
Um valor de data e hora UTC entra e o valor de data e hora local relativo ao servidor sai. Valores nulos retornam nulos.
fonte
Não existe uma maneira simples de fazer isso de maneira correta e genérica.
Antes de tudo, deve-se entender que a compensação depende da data em questão, o fuso horário e o horário de verão.
GetDate()-GetUTCDate
hoje fornece apenas o deslocamento hoje na TZ do servidor, o que não é relevante.Eu vi apenas duas soluções funcionais e tenho muita pesquisa.
1) Uma função SQL personalizada com um par de tabelas de dados base, como fusos horários e regras de horário de verão por TZ. Trabalhando, mas não muito elegante. Não posso publicá-lo, pois não possuo o código.
EDIT: Aqui está um exemplo deste método https://gist.github.com/drumsta/16b79cee6bc195cd89c8
2) Adicione um conjunto .net ao banco de dados, o .Net pode fazer isso com muita facilidade. Isso está funcionando muito bem, mas a desvantagem é que você precisa configurar vários parâmetros no nível do servidor e a configuração é facilmente interrompida, por exemplo, se você restaurar o banco de dados. Eu uso esse método, mas não posso publicá-lo, pois não possuo o código.
fonte
Nada disso funcionou para mim, mas isso abaixo funcionou 100%. Espero que isso ajude outras pessoas a tentar convertê-lo como eu.
fonte
declare @StandardOffset int = datediff (hh, GETUTCDATE(), GETDATE())
Aqui está uma versão que responde pelo horário de verão, compensada pelo UTC, e não está bloqueada em um ano específico.
fonte
Descobri que a função única é muito lenta quando há muitos dados. Então, eu fiz isso ingressando em uma função de tabela que permitiria o cálculo da diferença de horas. São basicamente segmentos de data e hora com o deslocamento da hora. Um ano seria de 4 linhas. Então a função de tabela
retornaria esta tabela:
Isso explica o horário de verão. Uma amostra de como é usada está abaixo e a postagem completa do blog está aqui .
fonte
fonte
A resposta de Ron contém um erro. Ele usa as 2:00 da manhã no horário local em que o equivalente ao UTC é necessário. Eu não tenho pontos de reputação suficientes para comentar a resposta de Ron, então uma versão corrigida aparece abaixo:
fonte
O registro de data e hora do UNIX é apenas o número de segundos entre uma data específica e a época do Unix,
SELECT DATEDIFF (SEGUNDO, {d '1970-01-01'}, GETDATE ()) // Isso retornará o registro de data e hora do UNIX no SQL server
você pode criar uma função para a hora local da data em conversão UTC do Unix usando a Função de deslocamento do país para carimbo de data e hora do Unix no SQL server
fonte
É simples. Tente isto para o Azure SQL Server:
Para o SQL Server local:
fonte
Para
@@Version
usuários do Azure SQL e > = SQL Server 2016, Abaixo está uma função simples usandoAT TIME ZONE
.Para tipos de valores que
@LocalTimeZone
podem assumir, acesse este link ou Vá paraKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
fonte
Como aviso - se você usar o seguinte (observe os milissegundos em vez de minutos):
Lembre-se de que a parte DATEDIFF nem sempre retornará o mesmo número. Portanto, não use-o para comparar DateTimes em milissegundos.
fonte
Descobri que essa função é mais rápida do que outras soluções usando uma tabela ou loops separados. É apenas uma declaração básica de caso. Como todos os meses entre abril e outubro têm um deslocamento de -4 horas (horário do leste), precisamos adicionar mais algumas linhas de casos para os dias seguintes. Caso contrário, o deslocamento é de -5 horas.
Isso é específico para uma conversão do UTC para o horário do Leste, mas funções adicionais de fuso horário podem ser adicionadas conforme necessário.
fonte
Isso deve conseguir tempo do servidor com o horário de verão
sysdatetimeoffset leva em consideração o horário de verão
fonte
Primeira função: configurada para o fuso horário italiano (+1, +2), alternar datas: último domingo de março e outubro, retornar a diferença entre o fuso horário atual e a data e hora como parâmetro.
O código é:
Então a função que converte a data
fonte
- obtenha o horário padrão indiano do utc
fonte
Isso pode ser feito sem uma função. O código abaixo converterá um horário UTC para Horário da montanha, contabilizando o horário de verão. Ajuste todos os números -6 e -7 ao seu fuso horário de acordo (ou seja, para EST, você ajustaria para -4 e -5, respectivamente)
fonte
Você precisa reformatar a sequência e converter para a hora correta. Nesse caso, eu precisava de tempo zulu.
fonte
Melhor maneira para Oracle:
Com data e hora codificada:
Result:
2018-10-28 00:00
Com nomes de colunas e tabelas:
fonte
Eu tenho um código para executar os horários UTC para Local e Local para UTC, o que permite a conversão usando um código como este
e
As funções podem suportar todo ou um subconjunto de fusos horários no IANA / TZDB, conforme fornecido pelo NodaTime - veja a lista completa em https://nodatime.org/TimeZones
Esteja ciente de que meu caso de uso significa que eu preciso apenas de uma janela 'atual', permitindo a conversão de tempos dentro do intervalo de aproximadamente +/- 5 anos a partir de agora. Isso significa que o método que eu usei provavelmente não é adequado para você, se você precisar de um período muito amplo, devido à maneira como gera código para cada intervalo de fuso horário em um determinado período.
O projeto está no GitHub: https://github.com/elliveny/SQLServerTimeConversion
Isso gera código de função SQL conforme este exemplo
fonte
Bem, se você armazenar os dados como data UTC no banco de dados, poderá fazer algo tão simples quanto
era sempre local do ponto do servidor e você não se atrapalhava com o AT
TIME ZONE 'your time zone name'
, se seu banco de dados fosse movido para outro fuso horário como uma instalação de cliente, um fuso horário codificado pode morder você.fonte
No postgres, isso funciona muito bem. Diga ao servidor o horário em que o horário é salvo, 'utc', e solicite a conversão para um fuso horário específico, neste caso 'Brasil / Leste'
Obtenha uma lista completa de fusos horários com a seguinte seleção;
Veja detalhes aqui.
https://popsql.com/learn-sql/postgresql/how-to-convert-utc-to-local-time-zone-in-postgresql
fonte
Aqui está um mais simples que leva o dst a levar em conta
fonte
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, GETUTCDATE(), '20150101'), GETDATE())
. Atualmente, estou em CEST (UTC + 2), mas o horário de verão não entrará em vigor no dia de Ano Novo, portanto, a resposta correta para mim seria 1 de janeiro de 2015 às 01:00. Sua resposta, como a resposta aceita, retorna 1 de janeiro de 2015 às 02:00.