Trabalhando com Data, Horas e Fusos Horários

Trabalhar com datas e horas pode ser uma tarefa bem complexa se não entendermos o básico desse dominio.

O que é tempo ?

A definição de Tempo não é simples. Uma forma mais simples seria definir o tempo como a sucessão ordenada e linear de instantes. Para medirmos a passagem do tempo, inventamos o conceito de tempo de referência e uma unidade temporal - como o segundo. Então, podemos falar de intervalos de tempo como o tamanho - em segundos - entre o instante A e um instante B. Ao fixar o ponto A num instante correspondente a um evento histórico, podemos falar de quanto tempo passou desde então. Isto nos permite chegar no conceito de calendário.

Escolher diferentes instantes de referência representa escolher diferentes épocas.

A passagem do tempo é medida por relógios que nos fizem em que instante estamos quando comparados a um instante de referência.

O que é uma data?

Para entender o que é uma data, precisamos primeiro entender o que é um calendário. Um calendário é um conjunto de regras que determinam como as datas mudam e como nomear as datas. Em particular, os calendários permitem converter tempo universal para datas e horas nesse calendário. Uma data é uma marca no calendário para um evento.

Datas apenas podem ser definidas com base num calendário. Várias culturas definiram os seus calendários e muitos deles persistem até hoje. Para evitar confusão e permitir que pessoas com culturas diferentes cheguem a um acordo sobre quanto se encontrar para um evento, a norma ISO estabelece um calendário especial baseado no Calendário Gregoriano, que define a época numa data hipotética para o nascimento de Cristo calculada a partir de eventos astronômicos e uma matemática avançada que considera os períodos de translação da Lua e da Terra.

Uma data é normalmente um conjunto de três números ordinais: o dia, o mês e o ano. Porque são números ordinais nunca são zero. Por exemplo, a data 1/2/1970 representa o primeiro dia, do segundo mês do milésimo nonocentésimo septuagésimo dia do calendário.

As regras de como esses números aumentam não é igual para todos os calendários. Normalmente o ordinal do dia é ligado ao passar de um dia e uma noite, equivalendo a uma rotação completa da Terra em torno do seu eixo. O ordinal do mês aumenta quando o número de dias do mês anterior chega num certo máximo. O número de ano aumenta quando o número de dias do último mês aumenta além de um certo máximo. No calendário Gregoriano existem 12 meses com números de dias variando entre 28 e 31. No Calendário Hebraico, por exemplo, o número de meses é variável podendo chegar a 13.

Tempo universal

Nas plataformas de programação permite que o valor do relógio interno do computador pode ser acessado e interpretam esse valor para uma época específica. A época escolhida depende da plataforma.

Tick Tack

Os computadores contêm uma memória do número de cliclos que passaram desde um momento pré-definido pelo fabricante. Estes ciclos são conhecidos como ticks. Cada fabricante estabelece um número de milisegundos para cada tick e, portanto, o instante atual se baseia em multiplar a contagem de quantos ticks aconteceram pelo número de milisegundos correspondente a cada um e somar com o momento de referência escolhido pelo fabricante.

As plataformas modernas tendem a escolher o que se chama a Época Unix que conta quanto tempo passou desde as zero horas do dia 1 de Janeiro de 1970 quanto medido por um relógio que esteja sobre o meridiano de Greenwich. Tempos medidos por relógios nestas condições são chamados tempos GMT (Greenwich Mean Time) ou Tempo Médio de Greenwich. Um inteiro de 64 bits é usado para contar os milisegundos desde esse instante.

O valor em milissegundos se deve à exatidão com que o relógio interno funciona. Alguns sistemas funcionam com ticks de 10 centésimos de segundo a cada ciclo, enquanto outros têm ciclos maiores ou menores. Isto significa que se o software perguntar qual é o instante atual com um intervalo menor que o aquele usado para os ticks, o retorno será o mesmo, e parece que o tempo não passou.

Sendo que Greenwich é uma localização na Inglaterra, um padrão subsequente da ISO modificou o nome para UT (Universal Time). É apenas uma alteração de nome já que a forma de medida é a mesma. Contudo, esta forma de medição do passar do tempo é baseada em eventos astronômicos.

Quando se decidiu medir o tempo usando relógios atômicos houve a necessidade de criar padrão novo de mensuração chamado UTC, Tempo Universal Coordenado.

Todos os computadores contam o mesmo tempo independentemente de onde estão.

Fuso horário

O Tempo Universal está relacionado com o movimento de rotação da terra, em particular relacionado ao movimento de rotação do meridiano de Greenwich. Neste sistema, se for meio-dia em Greenwich todos os relógios em todo globo apontariam meio-dia. Obviamente este não é um sistema prático. Seria interessante se pudéssemos relacionar o meio-dia à elevação local do sol, e não à elevação do sol em Greenwich. Para isso se inventou o conceito de Fuso Horário.

O Fuso Horário (Time Zone) é um valor em horas adicionado à, ou subtraido da, hora universal marcado por um relógio em Greenwich para obter a hora local.

Existem várias razões de por quê usar um fuso horário: localização geográfica, razões politicas e razões econômicas.

Fuso Horário Geográfico

O fuso horário geográfico é definido trigonometricamente definindo que a Terra tem 360 graus que correspondem a 24h. Isso equivale a 15 graus por hora. Portanto, a cada 15 graus a leste é somanda uma hora e a cada 15 graus a oeste é subtraida uma hora.

O fuso horário geográfico não tem implicações na vida civil e é mais utilizado para observações astronômicas e náuticas.

O fuso horário geográfico é escrito como a diferença horária relativamente ao horário em Greenwich. O fuso horário geográfico em Greenwich é GMT+00h00 , o fuso horário a 15 graus a leste seria GMT+01h00 e GMT-01h00 a oeste.

Fuso Horário Politico

Idealmente um país está apenas sob um fuso horário. Isso significa que mesmo geograficamente afastado um certo território utiliza o fuso horário politicamente imposto que não é igual ao Fuso Horário Geográfico. Isso implica em observações bastante diferentes da altura do Sol à mesma hora apontada pelo relógio em pontos diferentes do território.

O Fuso Horário Politico é imposto apenas pela lei com o fim de demonstrar soberania num território.

O Fuso Horário Politico é designado pelo par continente/cidade em que normalmente a cidade é uma cidade de referência, como uma capital. Por exemplo America/Los_Angeles, America/Sao_Paulo ou Europe/Paris. O Fuso Horário Politico pode ainda ser comum a uma região e nesse caso uma sigla é usada para resignar essa região, como por exemplo CST, PST e AST. Contudo, estas siglas são ambiguas e não devem ser utilizadas. Por exemplo, CST pode ser Central Standard Time, usado nos E.U.A, ou China Standard Time, usado na China.

Fuso Horário Econômico e o Horário de Verão

O Fuso Horário Econômico é estabelecido por razões econômicas, normalmente relacionadas com o consumo de energia. Ao modificar o Fuso Horário Politico para uma hora diferente num certo período do ano, o país pode poupar a energia que seria utilizada nesse período. Este efeito é conseguido alterando o horário de forma que o maior número de horas de sol pode ser utilizado no dia a dia dos habitantes assim diminuindo o consumo de energia electrica.

O novo horário é normalmente diferente do fuso horário politico por um valor de uma hora, a mais, ou a menos, e é normalmente imposto apenas no Verão. Por esta razão ganhou o nome de Horário de Verão, contudo, esta nomenclatura não é comum a todos os países. Em ingês é conhecido como Daylight Saving Time (Período de economia de luz do dia).

O horário de verão não tem que ser imposto em todo o território do país e, é imposto por lei, o que o torna um tipo especial do fuso horário politico.

Porque o mecanismo de horário de verão está ligado ao Fuso Horário Politico não existe uma representação especial para a localização geográfica do país e uso do mecanismo.

O Fuso Horário vigente em determinado período em determinado local é uma informação dinâmica já que é estabelecido com base em leis politicas.

Tempos Locais e Tempos Regionais

Porque relógios em posições diferentes da Terra não marcam o mesmo horário é importante distinguir quanto estamos falamos de momentos que acontecem na mesma região ou em regiões diferentes. Por exemplo, se uma pessoa almoçou às 12h45 em São Paulo, Brasil e uma almoçou às 12h45 em Tóquio, Japão podemos dizer que almoçaram simultaneamente? A resposta é não, porque os relógios têm uma diferença de 12h. Então, quando em São Paulo eram 12h45 em Tókio eram 00h45. Mas quem almoçou primeiro? A pessoa em Tókio almoçou primeiro, porque Tókio tem o relógio avançado relativamente a São Paulo.

Para nos ajudar é útil definir os seguintes conceitos:

  • Instante (Instant) - um certo momento do tempo.

  • Relógio (Clock) - nos permite saber qual é o instante atual.

  • Tempo Local (LocalTime)- indica uma hora, e suas frações, sem nenhuma relação com a data, região ou fuso horário. Usado, por exemplo, pelo médico que indica que o remédio deve ser tomado diáriamente às 8h30.

  • Data Local (LocalDate)- indica um dia, de um mês de um ano, sem nenhuma relação com tempos, região ou fuso horário. Usado para marcarmos compromissos: "nos encontramos para discutir o assunto no dia 14 de Abril de 2025"

  • Data e Hora Local (LocalDatetime)- indica ano, mês, dia, hora e suas frações, mas sem nenhuma relação com região ou fuso horário.

  • Data e Hora Regional (ZonedDatetime)- indica ano, mês, dia, hora e suas frações e também a região a que esses valores se referem. Esta quantidade pode ser comparada entre regiões do mundo.

Para cada conceito indiquei o nome da classe normalmente utilizado em bibliotecas modernas que trabalham com tempo. Estes nomes e conceitos vão nos ajudar a distinguir os diferntes cenários e a criar algoritmos corretos.

Relógiocs e o momento actual

É comum em aplicações antigas e sem preocupação com boas práticas ter código como este espalhado por várias classes:

 var now = DateTime.now();

Onde se utiliza um método estático - normalmente chamdo now - para obter a momento atual. Esta não é uma boa ideia. O momento atual deve sempre ser obtido de um relógio (Clock). O objeto clock deve ser injetado onde for necessário e sempre usá-lo para obter o momento atual.

A vantagem é que, durantes a execução de testes, a data e hora podem ser ajustadas pelo teste para simular uma data e hora especificas ou simular a passagem de tempo. Usando um relógio real seria dificil testar a passagem de anos, por exmplo.

Cálculos com datas e tempos

Suponhamos o nosso exemplo das pessoas almoçando em São Paulo e em Tókio. Quando a pessoa olha o seu relógio pessoal ela obtém um instante atual local. Esse instante é então convertido utilizando um calendário para uma data e hora locais (LocalDateTime).

Não podemos comparar objetos LocalDateTime coletados em regiões diferentes. Precisamos então comparar os momentos em uma mesma região. Para isso convertemos o LocalDateTime obtido em são Paulo para o ZonedDateTime correspondente, considerando o fuso horario de São Paulo naquele momento. Fazemos o mesmo para o LocalDateTime de Tókio. Obtemos o seguinte:

  • 12h45 do dia 3/4/2025 em São Paulo = 2025-04-03 12:45 GMT-3h00

  • 12h45 do dia 3/4/2025 em Tókio = 2025-04-03 12:45 GMT+9h00

Agora temos três opções

  • Transferimos o ZonedDateTime de São Paulo para Tókio

  • Transferimos o ZonedDateTime de Tókio para São Paulo

  • Transferimos ambos para um fuso horário de referência, como UTC.

Transferir, significa calcular o momento que um relógio na outra região indicaria, no mesmo momento, em que o relógia da região lida, indicou o valor que temos.

Para transferir para UTC basta aplica o simétrico do fuso horario. Se São Paulo está a -3h, então somamos 3h. Se Tókio está a +9h, subtraimos 9h.

  • Almoço em São Paulo = 2025-04-03 12:45 GMT-3h00 = 2025-04-03 15:45 GMT+0h00

  • Almoço em Tókio = 2025-04-03 12:45 GMT+9h00 = 2025-04-03 3:45 GMT+0h00

Podemos então ver que quanto a pessoa em Tókio almoçou eram 3h45 da madrugada em Greenwich, mas quando a pessoa em São Paulo almoçou eram 15h45 da tarde em Greenwich, ou seja, muito depois. 12h depois, exatamente. Sabemos então que a pessoa em Tókio almoçou 12h antes que a pessoa em São Paulo.

Vejamos como chegar na mesma conclusão transferindo o momento em São Paulo para Tókio.

  • Almoço em São Paulo = 2025-04-03 12:45 GMT-3h00 = 2025-04-04 0:45 GMT+9h00

  • Almoço em Tókio = 2025-04-03 12:45 GMT+9h00

Veja que obtemos o momento em Tókio somando 12h ao momento original. 12 é a soma de 3 - a diferenção de São Paulo até Greenwich com 9 - a diferença de Greenwich até Tókio. Podemo então ver que quando a pessoa em São Paulo almoçou, já eram 0h45 do dia seguinte em Tókio, então claramente aconteceu depois e, portanto, a pessoa em Tókio almoçou 12h antes que a pessoa em São Paulo.

A lição é que não podemos comparar momentos definido localmente, com outros definidos localmente em locais diferentes e precisamos considerar o fuso horário e a diferença entre fusos horários para concluirmos se os momentos são simultâneos, ou não.

Tempo e Persistência

Vimos que só podemos comparar momentos expressos no mesmo fuso horário. Por isso, é importante que ao persistir momentos todos estejam no mesmo fuso horário. O fuso UTC/GMT é especialmente fácil de trabalhar.

Em certas ocasiões é também necessário saber em que fuso horário a pessoas estava no momento em que a informação foi gravada. Se precisar dessa informação, guarde-a à parte em outra coluna.

Tempo e UI

Datas, horas e momentos em geral devem sempre ser apresentados ao usuário no referencial temporal que ele escolheu. Essa escolha pode ser implicita ou explicita. Ao escolher um navegador, em um certo computador em certa região, implicitamente escolheu que os dados temporais sejam referidos a essa localização geográfica. Mas, o software pode permitir ao usuário escolher em qual fuso horario quer ver os dados apresentados.

O importante é que sempre os dados sejam apresentados em correlação com o referencial escolhido.

Tempo dos dados

Para que a aplicação cliente possa fazer as contas necessárias, os dados devem ser transiatados no formato UTC, isso simplifica muito os cálculos. O mesmo vale para dados vindo de bancos de dados.

A applicação, cliente ou servidora, fará os necessários ajustes se, e quando, precisar fazer cálculos ou comparações.

Scroll to Top