Como tornar um sistema legado sensível ao fuso horário?

5

Eu preciso implementar fusos horários em um sistema Delphi muito grande e antigo, onde há um banco de dados central do SQL Server e possivelmente centenas de instalações de clientes em todo o mundo em fusos horários diferentes. O aplicativo já interage com o banco de dados usando apenas a data / hora do servidor de banco de dados. Portanto, todos os registros de hora salvos no banco de dados e nas máquinas clientes são a data / hora do servidor de banco de dados quando isso aconteceu, nunca o horário da máquina cliente.

Assim, quando um cliente está prestes a exibir a data / hora de algo (como uma transação) que vem desse banco de dados, ele precisa mostrar a data / hora convertida para o fuso horário local. É aqui que me perco.

Eu naturalmente presumo que deve haver algo no SQL para reconhecer o fuso horário e converter um campo DateTime dinamicamente. Eu não tenho certeza se tal coisa existe embora. Se assim for, isso seria perfeito, mas se não, eu preciso descobrir outra maneira.

Este sistema Delphi (vários projetos) utiliza o banco de dados do SQL Server usando componentes ADO, controles com reconhecimento de dados VCL e QuickReports (usando fontes de dados). Portanto, há muitos lugares em que os dados vão diretamente da consulta do banco de dados para a renderização na tela, sem nenhum código para realmente colocar esses dados na tela. No final, preciso saber quando e como devo obter o tempo corretamente convertido?

Qual é a maneira correta de garantir que eu processe datas e horários corretamente em um aplicativo herdado?

    
por Jerry Dodge 07.12.2012 / 18:25
fonte

2 respostas

5

Datas e fusos horários são coisas complicadas e, geralmente, não importa em que tipo de pilha de tecnologia você está trabalhando, raramente há uma solução imediata.

A maioria dos bancos de dados armazenará uma data ou registro de data e hora como pouco mais que a data exata ou o registro de data e hora que foi dado a ela. Ao conversar com um banco de dados por meio de consultas, eles geralmente pressupõem que todas as datas e registros de data e hora representam um ponto no tempo sob o mesmo fuso horário. Em outras palavras, se eu escrever uma consulta para ver se 2 de agosto de 2012 16:10 é antes da mesma data às 17:10, então, que será avaliado como verdadeiro retornando-me esse registro. Suponha que o registro tenha sido salvo às 16h10, horário padrão do leste dos EUA, quando meu servidor de banco de dados estiver no horário padrão do Pacífico. O banco de dados é independente de fuso horário e, agora, minha consulta não está retornando os dados esperados.

Converta todas as datas e horários do aplicativo em UTC ou GMT antes de persistir

Idiomas como Java, Javascript e C # tratam datas e horários de maneira um pouco diferente. Eles geralmente medem o tempo como um número de milissegundos a partir de um determinado ponto universal no tempo. Este é o horário universal, já que o número específico de milissegundos de 0 representa um número de diferentes datas ou horas em diferentes fusos horários em qualquer ponto dado. A maioria dessas linguagens geralmente tem uma sólida API de data e hora ou uma boa biblioteca de terceiros pode ser encontrada para tornar a visualização dessa contagem em milissegundos em um número de fusos horários o mais simples possível.

A menos que seja especificado de outra forma, se eu usar uma API de acesso a dados padrão em um idioma comum, a maioria pegará um objeto de data e o converterá na data e hora do fuso horário padrão do servidor no formato de banco de dados especificado. Descubra como os dados do seu idioma acessam a API e o banco de dados armazena as datas e como elas as interpretam do banco de dados e tentam armazenar suas datas no nível do banco de dados no GMT. Da mesma forma, ao consultar, certifique-se de que os objetos ou variáveis Date em seu idioma estejam representando uma contagem em milissegundos equivalente à hora da data GMT armazenada no banco de dados.

Fusos horários persistentes para datas usadas na lógica de negócios

O que quero dizer com isto é que, talvez, se você tiver uma coluna Data de modificação em seu banco de dados, pode não ser importante para a lógica de negócios, no entanto, uma coluna Data de compromisso provavelmente será importante.

Em algum lugar no seu esquema, você precisa determinar onde os dados específicos do código do idioma estão armazenados e armazenar o fuso horário para definir esse código de idioma na tabela pai apropriada. Sua lógica de negócios que está considerando datas ou sua lógica de apresentação que está preparando datas para exibição deve ser capaz de buscar o fuso horário apropriado para que, quando eu estiver comparando as 16h10 às 17h10, que eu esteja comparando datas do Tempo. 4:10 pm EST e 4:10 pm PST são pontos separados no tempo universal. Novamente, uma boa API de data e hora ou biblioteca de terceiros facilita a comparação de datas, quando você entende a natureza subjacente de como as datas funcionam nessa linguagem de programação.

Lógica de negócios Deve ser refatorada para estar ciente do fuso horário.

Lógica de apresentação Deve ser refatorada para apresentar um valor de exibição que exiba adequadamente os dados corretos de acordo com o fuso horário especificado.

Um pensamento final a ser considerado ao realizar este trabalho é escrever exaustivos testes de unidade que exaurem completamente muitos tipos de combinações de Data e Hora para garantir que toda a lógica de negócios funcione como esperado.

    
por 07.12.2012 / 19:23
fonte
0

O problema aqui é que as visualizações estão conectadas diretamente aos modelos.

Embora isso pareça horrível de se conseguir em delphi, o primeiro passo é impor uma separação de interesses.

Você pode usar uma abordagem MVVM e ter modelos de visualização intermediários que realizam transformação localizada dos valores do banco de dados para exibição. Esses mesmos modelos de visualização podem transformar a entrada localizada no fuso horário que o banco de dados espera ao armazenar dados.

O MVP ou alguma outra variante MV * pode ser mais adequada, dependendo de como você está atualmente configurado e de seus requisitos exatos, mas você obtém a imagem. A vantagem de todo esse trabalho é que futuras mudanças localizadas serão muito mais fáceis de realizar.

    
por 30.12.2014 / 17:36
fonte

Tags