Bugs de timezone passam por testes comuns porque a maioria dos dias parece normal. Depois chega uma transição de horário de verão, uma reunião internacional ou uma mudança política. Um horário local pode não existir ou pode acontecer duas vezes. O problema geralmente é um modelo que descartou cedo demais a diferença entre instant, horário local e zona.

Offset e timezone não são a mesma coisa

Offset diz a diferença para UTC em um instante. Uma timezone IANA como America/Sao_Paulo contém regras históricas e futuras. O mesmo lugar pode usar offsets diferentes ao longo do tempo.

Para registrar um evento passado, offset pode bastar. Para agendar o futuro, a identidade da zona preserva a intenção.

Alguns horários não existem

Quando o relógio avança, uma faixa local pode ser pulada. Uma reunião às 02:30 talvez seja impossível. A aplicação deve rejeitar, mover ou pedir confirmação.

Corrigir silenciosamente surpreende o usuário. A política precisa aparecer na interface e no contrato.

Alguns horários acontecem duas vezes

Quando o relógio volta, 01:30 pode referir-se a dois instantes. Sem informação adicional, a conversão é ambígua.

Logs devem guardar instant UTC. Entradas futuras devem preservar timezone e resolver a ambiguidade explicitamente.

Regras mudam por decisões políticas

Países alteram offsets e horário de verão. Bibliotecas dependem de tzdata atualizado. Um container antigo pode calcular horários errados mesmo com código correto.

Eventos futuros não deveriam ser convertidos definitivamente cedo demais quando a intenção é permanecer em um horário local.

Datas locais não são instantes

Aniversário, vencimento e dia de relatório podem ser datas sem horário. Converter para meia-noite UTC pode deslocar o dia para alguns usuários.

Adicionar 24 horas também não é sempre igual a adicionar um dia de calendário. As operações respondem a perguntas diferentes.

A interface deve explicar consequência

Ao criar uma reunião, mostre timezone e efeito para participantes. Ao editar uma série, diga se muda o horário local, o instant ou apenas uma ocorrência.

Convites atualizados e auditoria ajudam a resolver divergências. Um aviso antes de salvar custa menos que uma reunião perdida.

APIs precisam de valores inequívocos

2026-03-29 02:30 sem timezone não define um instant. A API deve pedir ISO 8601 com offset ou campos separados para data, hora e zona.

Erros devem distinguir horário inexistente, ambíguo e zona ausente. “Data inválida” não ajuda a integração.

Calendários externos precisam da mesma intenção

Uma série recorrente exportada apenas como instantes perde a regra local. Quando o formato permite, envie timezone, recurrence rule e exceções.

Mudanças devem informar se atingem toda a série ou uma ocorrência. Clientes diferentes podem interpretar metadata incompleta de modos distintos.

Notificações precisam ser recalculadas com cuidado

Uma lembrança “30 minutos antes” é uma duração relativa ao instant da ocorrência. Já uma mensagem “às 8h no dia anterior” pode depender do calendário local. Guardar apenas o timestamp final dificulta recalcular depois de editar timezone ou série.

Ao mudar um evento, a aplicação deve cancelar ou atualizar jobs antigos de notificação. Caso contrário, o usuário recebe alertas duplicados ou no horário anterior.

Interfaces devem mostrar timezone de forma humana

Abreviações como CST são ambíguas. Nomes de cidade ou região, offset atual e data ajudam mais. Para eventos futuros, mostrar apenas o offset pode enganar porque ele pode mudar até a ocorrência.

A preferência do usuário para exibição não deve substituir a timezone que define a regra do evento.

Atualizações de tzdata precisam de observação

Depois de atualizar a base de fusos, eventos futuros podem calcular instants diferentes. Sistemas críticos podem comparar antes e depois, registrar alterações e avisar responsáveis quando o impacto é relevante.

Esse processo trata mudanças políticas como atualização de dados de domínio, não apenas patch de sistema operacional.

Busca e relatórios precisam definir timezone

“Pedidos de hoje” depende de qual dia local. Um relatório global pode usar UTC; um relatório de loja pode usar a zona da unidade. Consultas que truncam timestamps sem timezone explícita produzem números diferentes entre banco, aplicação e dashboard.

O contrato do relatório deve nomear zona e boundaries. Isso torna os resultados reproduzíveis e evita discussões sobre totais próximos da meia-noite.

Futuras mudanças devem preservar intenção

Quando o usuário muda sua timezone de preferência, eventos já agendados não devem necessariamente mudar. A aplicação precisa distinguir timezone de exibição e timezone que pertence ao evento. Misturar as duas desloca compromissos antigos.

Testes devem cobrir transições

Inclua início e fim de horário de verão, zonas de meia hora, hemisférios diferentes e regras históricas. Fixe timezone no teste; não dependa da máquina CI.

Execute regressões após atualizar tzdata. Uma regra correta hoje pode mudar no futuro.

Armazene a intenção original

Um sistema confiável distingue instant, local date, local time, timezone e duration. Preservar essa diferença transforma daylight saving em regra de conversão, não surpresa.

Depois que a zona é perdida, formatar melhor o timestamp não recupera o que o usuário queria.