O tempo sempre anda para a frente. (foi mal, Einstein)

É bastante comum assumir que se eu pegar um tempo agora e depois pegar o tempo no futuro, o do futuro é maior que o do passado. Parece óbvio, mas isso não pode ser assumido como verdade para qualquer coisa maior que um rápido e não importante benchmark. O que acontece aqui é que as timezones definem momentos de mudança de horário, o mais comum é o famoso Horário de Verão. Nele, em um momento específico do ano o relógio vai voltar uma hora e o tempo irá se repetir. Bugs por conta disso são comuns em calculo de taxas. Por exemplo: calcular o número de transações por segundo. Eu meço o número de transações agora e o tempo, espero, e meço novamente. Faço uma divisão simples, e vualá, posso chegar em um número negativo. Uma solução simples para evitar mudanças de timezone é utilizar UTC sempre. Mas veja abaixo.


Ok, então em UTC o tempo sempre anda para a frente.

De certa forma sim, mas não realmente. O tempo correto é medido por relógios atômicos e o seu computador (muito provavelmente) não tem um. O que ele tem é um oscilador que tenta se manter o mais perto possível, mas que erra e vai divergindo do tempo correto. Para resolver esse problema existe um serviço e protocolo chamado NTP, que obtém o tempo correto pela Internet, se comunicando com algum relógio atômico. Sempre que esse serviço descobre que o seu relógio está errado, ele o corrige, modificando o horário atual as vezes para mais... e as vezes para menos. O erro acumulado aqui tende a ser de menos de 1 segundo por dia, mas ainda assim é fato que o tempo pode ser corrigido e voltar para trás. Se você quer um relógio que sempre vá para a frente, use um relógio monotônico.


Um dia tem 24 horas.

Já vimos que em timezones existe o Horário de Verão que fazem alguns dias terem 25 horas e outros 23 horas. Mas vamos então falar de UTC aqui. Ela deveria não ter nenhum tipo de ajuste e seguir sempre constante e linear, certo? Não. A UTC foi criada com o objetivo de ser o mais próxima possível do ciclo solar no equador. Então estações do ano não chegam a importar aqui, mas tem um problema maior: A Terra está girando mais devagar a cada ano. E isso faz os dias serem mais curtos, atualmente estamos errando por 1 segundo a cada 800 dias, e isso tende a aumentar. Para combater o problema existe o "Segundo Bissexto", é como aquele dia a mais a cada 4 anos (4?), mas como um segundo que entra a mais a cada certa de 19 meses. Então alguns dias, mesmo no UTC, tem 24 horas e 1 segundo, sendo adicionados no fim do dia e representados como 23h59m60s. A maioria das bibliotecas sequer considera que isso existe e mostram informações incorretas.


29 de Fevereiro acontece a cada 4 anos.

As regras aqui são bem precisas: Acontece a cada 4 anos. Exceto nos anos múltiplos de 100. Mas acontece nos múltiplos de 400. É uma exceção facilmente esquecida considerando que todos os anos múltiplos de 4 entre 1901 e 2099 foram bissextos, mas se estiver considerando um período maior de tempo, precisa levar em consideração.


Se tenho duas datas, elas estão na mesma timezone.

Se eu obtive duas datas, elas estão na mesma timezone e eu posso ler o dia do mês diretamente e comparar, certo? Não. Muitos formatos de transmissão e bancos de dados armazenam a data vinculada a sua timezone (afinal uma data sem timezone não faz sentido, vai assumir que é UTC?). O que faz com que você possa ter datas de timezones diferentes no mesmo código. Repare ainda que mesmo que você meramente leia a data atual do computador, lembre que existem usuários e eles podem mudar a timezone do sistema operacional no meio da execução do seu programa, inclusive no meio daquela rotina crítica que ninguém mudaria a timezone no meio.


Todos os meus clientes estão na mesma timezone.

Bem vindo ao Mundo, seus clientes tem várias timezones. Sempre que um tempo trafegar entre um e outro e você precisa lidar com isso. A correção não é pedir para seu usuário ajustar a timezone dele.


O relógio mostra o tempo correto, na timezone em que ele está. Ou ao menos está a poucos segundos disso.

Lembra do NTP que fica corrigindo o tempo? Pois. E se o computador nunca usou a internet desde que foi ligado pela primeira vez (câmeras fotográficas por exemplo)? Pois. E se um usuário mexeu? Pois. Não assuma que o tempo está correto. Nem mesmo próximo. Lidar com esse problema é difícil.


Tudo bem, mas se o relógio do cliente está errado, ao menos será uma diferença constante para o relógio do meu servidor, que está correto.

Errado em tantos níveis... Leia tudo acima.


Se eu programar esperar por 1 minuto, vou ser alertado 1 minuto depois.

Mesmo que você use um relógio monotônico (deveria) e mesmo que seu computador seja nas melhores condições possíveis, ele ainda tem outras coisas para fazer, outras tarefas. Ou você acha que seu programa é o centro do universo? Um temporizador faz com que a tarefa seja agendada para execução e naquele momento específico será colocada na fila de processos ativos, a ser gerenciada pelo sistema operacional. Este vai fazer o melhor que puder para executar tudo que precisa. Mas ainda assim, vai errar por alguns milisegundos.


Ok, se eu programar para esperar por 1 minuto, vou ser alertado em não mais que... sei lá... 1 hora depois.

A ideia é que ao menos o temporizador vai funcionar para algum momento próximo da tempo programado né? Não. Quando você fecha a tampa do seu notebook, ele "dorme", isso quer dizer que entra em suspenção e nenhuma tarefa é executada até que seja aberto novamente. Isso pode demorar dias. E não precisa ser um notebook. Celulares fazem bastante esse comportamento quando estão com a tela apagada, eles suspendem e restauram em ciclos para economizar o máximo possível de bateria, então não assuma nada aqui.


Certo, mas se eu ler a hora de quando programei o temporizador e a hora de quando foi acionado, saberei exatamente a diferença. E já aprendi, usando relógio monotônico.

Faz sentido, exceto se o relógio monotônico do seu computador também dormiu. Isso geralmente não acontece, afinal o objetivo dele é manter a hora certa. É algo físico ali ligado sempre. Exceto quando você está em uma Máquina Virtual. Já ocorreu em algumas de ser 13h02 e entrar no modo de suspenção do computador, passar horas, retornar e ainda ser 13h02 no relógio. Mas esse de fato é um caso bem isolado.


O Horário de Verão sempre acontece do mesmo jeito, ou então é avisado com antecedência.

As diferenças de timezone, como o Horário de Verão e demais correções históricas não acontecem de forma regular e são decidias por grupos humanos, dessa forma é mantida nos computadores uma enorme tabela de ajustes de timezone, que é seguida pelo sistema operacional. Nela está todos as decisões de políticos e demais grupos com poder de alterar o tempo. Só que ela pode estar desatualizada, ou decisões serem tomadas muito em cima da hora e não ser tempo suficiente para atualização ser propagada. Aconteceu na entrada do Horário de Verão na Bahia em 2018, a Bahia ia entrar, mas a decisão foi revogada e não houve tempo hábil de a atualização chegar em vários Androids. Eles entraram no horário de verão de forma automática, erroneamente.


Fevereiro sempre tem 28 ou 29 dias.

Sempre. Exceto uma vez.


O dia antes de Sábado é uma Sexta.

Geralmente é, mas temos políticos e economia interferindo com computadores.