Meu servidor de desenvolvimento local está no Oriente Médio, mas meu servidor de produção está no Reino Unido.
Preciso mostrar a data para o usuário no fuso horário. Por exemplo, se um usuário estiver na Arábia Saudita, preciso mostrar a hora de acordo com o formato da Arábia Saudita.
Devo criar uma nova tabela de banco de dados chamada TimeZone e salvar a Hora no UTC?
sql-server
sql-server-2008
timezone
user960567
fonte
fonte
Respostas:
Infelizmente, não há solução rápida para isso. A internacionalização de um aplicativo deve fazer parte das primeiras discussões de design, pois realmente se concentra em várias áreas diferentes, incluindo comparações de data / hora e formatação de saída.
De qualquer forma, para seguir o caminho certo, é essencial armazenar as informações de fuso horário com o tempo . Em outras palavras, perceber que a data / hora não
20130407 14:50
tem sentido sem (a) incluir o deslocamento UTC atual do fuso horário (nota 1) ou (b) garantir que toda lógica que insere esses valores primeiro converta em um determinado deslocamento fixo ( provavelmente 0). Sem uma dessas coisas, dois valores de tempo são incomparáveis e os dados estão corrompidos . (O último método é brincar com fogo (nota 2) , a propósito; não faça isso.)No SQL Server 2008+, você pode armazenar o deslocamento diretamente com o horário, usando o
datetimeoffset
tipo de dados. (Para completar, em 2005 e antes, eu adicionaria uma segunda coluna para armazenar o valor de deslocamento UTC então atual (em minutos).)Isso facilita para um aplicativo do tipo desktop, pois essas plataformas normalmente têm mecanismos para converter automaticamente uma data / hora + fuso horário em um horário local e depois formatar a saída, tudo com base nas configurações regionais do usuário.
Para a Web, que é uma arquitetura inerentemente desconectada, mesmo com os dados de back-end configurados corretamente, é mais complexo porque você precisa de informações sobre o cliente para poder fazer a conversão e / ou formatação. Isso geralmente é feito por meio das configurações de preferência do usuário (o aplicativo converte / formata as coisas antes da saída) ou simplesmente mostra as coisas com o mesmo formato fixo e deslocamento de fuso horário para todos (que é o que a plataforma Stack Exchange atualmente faz).
Você pode ver como se os dados de back-end não estiverem configurados corretamente, muito rapidamente eles ficarão complicados e invasivos. Eu não recomendaria seguir nenhum desses caminhos porque você acabará tendo mais problemas no final da linha.
Nota 1:
O deslocamento UTC de um fuso horário não é fixo: considere o horário de verão em que o deslocamento UTC de uma zona varia em mais ou menos uma hora. Também as datas de horário de verão das zonas variam regularmente. Portanto, o uso
datetimeoffset
(ou um composto delocal time
eUTC offset at that time
) resulta na recuperação máxima de informações.Nota 2:
É sobre o controle de entradas de dados. Embora não exista uma maneira infalível de validar valores recebidos, é melhor impor um padrão simples que não envolva cálculos. Se uma API pública espera um tipo de dados que inclua um deslocamento, esse requisito ficará claro para o chamador.
Se não for esse o caso, o chamador deve confiar na documentação (se a ler), ou o cálculo é feito incorretamente etc. Há menos modos de falha / erro ao exigir um deslocamento, especialmente para um sistema distribuído ( ou apenas web / banco de dados em servidores separados, como o caso aqui).
Armazenar o deslocamento de qualquer maneira mata dois coelhos com uma cajadada; e mesmo se isso não for necessário agora , disponibilizará a possibilidade posteriormente, se necessário. É verdade que é preciso mais armazenamento, mas acho que vale a pena a troca, porque os dados são perdidos se nunca forem gravados.
fonte
datetimeoffset
significa "esta é a hora local do usuário / computador quando a coisa aconteceu" - não precisamos saber se o horário de verão estava em vigor ou não, porque o deslocamento UTC fornecido está sempre lá (incorporado aodatetimeoffset
valor).Eu desenvolvi uma solução abrangente para conversão de fuso horário no SQL Server. Consulte Suporte ao fuso horário do SQL Server no GitHub .
Ele lida adequadamente com conversões entre fusos horários e para e do UTC, incluindo o horário de verão.
É semelhante em conceito à solução "T-SQL Toolbox" descrita na resposta do adss, mas usa os fusos horários mais comuns da IANA / Olson / TZDB em vez dos da Microsoft e inclui utilitários para manter os dados mantidos como novas versões do TZDB sair.
Exemplo de uso (para responder ao OP):
Veja o leia-me no GitHub para APIs adicionais e explicações detalhadas.
Além disso, observe que, como se trata de uma solução baseada em UDF, ela não foi projetada com o desempenho como objetivo principal. Ainda seria melhor se essa funcionalidade fosse incorporada ao SQL Server, da mesma forma que a
CONVERT_TZ
função existe no Oracle e no MySQL.fonte
O SQL Server fez modificações em 2005 em diante, onde o fuso horário interno é salvo no UTC. Isso se deve, em grande parte, à replicação geográfica e aos projetores de HA que envolvem o envio de logs, e os tempos de envio de logs salvos em diferentes fusos horários impossibilitavam o método antigo de restaurá-los.
Assim, salvar tudo internamente no horário UTC permitiu que o SQL Server funcionasse bem globalmente. Esse é um dos motivos pelos quais o horário de verão é difícil de lidar no Windows, porque outros produtos da Microsoft, como o Outlook, também salvam a data / hora internamente como UTC e criam um deslocamento que precisa ser corrigido.
Eu trabalho em uma empresa em que temos milhares de servidores (embora não sejam servidores MS SQL, mas todos os tipos de servidores) espalhados por todo o mundo, e se não forçássemos tudo especificamente a UTC, todos ficaríamos loucos muito rapidamente.
fonte
Eu desenvolvi e publiquei o projeto “T-SQL Toolbox” no codeplex para ajudar qualquer pessoa que lute com a manipulação de data e hora e fuso horário no SQL Server. É de código aberto e totalmente gratuito.
Oferece UDFs fáceis de conversão de data e hora usando T-SQL simples com tabelas de configuração adicionais prontas para uso.
No seu exemplo, você pode usar o seguinte exemplo:
Isso retornará o valor de data e hora convertido para seu usuário.
Uma lista de todos os fusos horários suportados pode ser encontrada na tabela "DateTimeUtil.Timezone" também fornecida no banco de dados T-SQL Toolbox.
fonte
Talvez esteja faltando algo óbvio, mas se tudo o que você quer fazer é exibir a data usando o fuso horário do usuário e o formato do idioma, a maneira mais simples é sempre armazenar as datas no UTC no banco de dados e permitir que o aplicativo cliente converta do UTC para o local fuso horário e use as configurações regionais do usuário para formatar a data adequadamente.
fonte