Quando você para para pensar, o conceito de tempo no desenvolvimento é mais complexo do que parece
A maioria dos programadores tratam o tempo como algo binário: ou você marca um relógio, ou não marca. Na prática, existem camadas de complexidade que começam a aparecer quando seu sistema precisa lidar com latência, fuso horário e medições precisas de performance. Vou passar por alguns formatos que aparecem no dia a dia do desenvolvimento.
Unix timestamp, monotonic time e wall clock time são exemplos de diferentes formas de tempo
O Unix timestamp (também chamado de epoch time) conta segundos desde 1º de janeiro de 1970 às 00:00:00 UTC. É útil para armazenamento porque é uma linha reta. Você pode comparar dois timestamps diretamente sem se preocupar com fusos horários. O problema é que ele não leva em conta saltos de horário. Se o servidor for ajustado manualmente ou receber um NTP update, o timestamp pode pular para trás ou para frente, quebrando cálculos de duração. Já o monotonic time mede intervalos desde um ponto arbitrário no início do sistema. Não corresponde a nenhum relógio do mundo real. Ele nunca volta atrás, o que o torna perfeito para medir tempo decorrido entre duas operações. Em Python, você acessa isso via time.monotonic(). No Go, é time.Now() subtraindo dois momentos. A desvantagem? Ele não serve para marcar eventos no calendário. Se você precisa saber que algo aconteceu às 14h30, o monotonic time é inútil para esse fim.
O wall clock time é o que todo mundo usa por padrão. É o relógio da parede, ajustável por usuários e pelo NTP. Ele representa a hora real, mas tem uma fraqueza crítica: pode mudar de direção. Um bom exemplo disso é quando um servidor em produção teve sua hora atrasada 5 segundos por uma correção de NTP durante uma transferência de arquivo. O sistema achou que o arquivo estava sendo transferido no futuro, gerando conflitos de lock e logs confusos. O workaround foi usar monotonic time para medições internas e wall clock apenas para exibição ao usuário final. Outro formato relevante é o ISO 8601. Ele estrutura datas e horas de forma legível por humanos: 2024-03-15T14:30:00Z. O Z no final indica UTC. Esse formato é amplamente adotado em APIs REST porque resolve ambiguidades de fuso horário quando usado corretamente. O problema comum que vejo é gente gravando datas sem o sufixo Z ou com offset errado. Uma API que recebia datas em horário brasileiro sem especificar o offset acabou cruzando dados de dois dias diferentes em relatórios mensais. A correção foi forçar parsing rigoroso com validação de timezone na entrada.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Tem também o Julian Day Number, que conta dias desde 1º de janeiro de 4713 a.C. no calendário juliano. Parece uma curiosidade acadêmica, mas aparece em sistemas astronômicos, bancos de dados geoespaciais e legado industrial. Quem trabalha com telescópios ou satélites vai encontrar isso regularmente. Não é prático para desenvolvimento web comum, mas entender sua existência evita surpresas ao integrar com APIs científicas.
Como escolher o formato certo para cada situação
Não existe formato universal. A escolha depende do que você está resolvendo. Para armazenar data e hora de um evento num banco de dados, use UTC com ISO 8601. Para medir performance de uma função, use monotonic time. Para calcular idade ou diferença entre datas visíveis ao usuário, converta para o fuso horário correto no momento da exibição, nunca no armazenamento. Um erro frequente é converter UTC para o fuso do usuário no banco de dados. Isso gera inconsistências quando o usuário muda de fuso ou quando há mudança de horário de verão. A conversão deve acontecer na camada de apresentação, mantendo o banco de dados limpo e consistente.
Outro problema comum é confiar cegamente no relógio do sistema para operações críticas. Se seu serviço precisa garantir ordem estrita de eventos, use sequenciadores ou vetores de caos em vez de timestamps. Em sistemas distribuídos, dois servidores podem ter timestamps idênticos para eventos diferentes, e a ordem fica ambígua. Ferramentas como Redis ou bancos orientados a eventos resolvem isso com IDs monotônicos independentes do relógio. Aprender a distinguir esses formatos economiza debugging noturno. Eu passei duas semanas rastreando um bug onde timestamps de logs pareciam fora de ordem em um cluster de Kubernetes. O problema era que cada pod tinha seu próprio relojinho, e a sincronização NTP estava dessincronizada entre nós. A solução final foi migrar para monotonic time para ordering interno e aceitar que logs entre nós diferentes não poderiam ser comparados cronologicamente de forma confiável.
O essencial é saber qual ferramenta usar em qual contexto. Não adianta dominar todos os formatos se você não souber quando cada um se aplica. Na prática, isso se resume a uma pergunta simples: você precisa saber que hora é ou precisa saber quanto tempo passou. A resposta define tudo.