UTC não é GMT, e offset não é fuso
Quatro palavras que parecem sinônimos são a raiz de quase todo bug de data. UTC (Tempo Universal Coordenado) é uma escala de tempo, a régua contra a qual o mundo mede instantes. GMT (Greenwich Mean Time) é o antecessor histórico dessa régua, hoje usado como um fuso legado (o do Reino Unido no inverno). Um offset é apenas um deslocamento numérico em relação ao UTC, como −03:00. E um fuso IANA, como America/Sao_Paulo, é uma regra viva: diz qual offset vale em cada data, incluindo se, quando e por quanto tempo há horário de verão. Confundir a régua, o número e o livro de regras é onde a maioria dos calendários e agendadores quebra.
- UTC
- A escala de tempo civil de referência. Não tem localização: 12:00 UTC é o mesmo instante no planeta inteiro.
- GMT
- Greenwich Mean Time. Historicamente a base do tempo mundial; hoje, na prática, um nome de fuso (UTC+00:00 no inverno britânico). Para engenharia, prefira dizer UTC.
- TAI
- Tempo Atômico Internacional: a contagem ininterrupta de segundos atômicos, sem nenhum ajuste. O UTC é o TAI menos um número inteiro de segundos bissextos.
- Offset
- A diferença entre um relógio local e o UTC num instante, como −03:00 ou +05:30. É um fato sobre um momento, não sobre o futuro.
- Fuso IANA
- Um identificador Área/Local (America/Sao_Paulo) que carrega o histórico e as regras futuras de offset de uma região, inclusive as de horário de verão.
A distinção que mais importa é entre offset e fuso. −03:00 diz onde o relógio está agora; America/Sao_Paulo diz onde ele estará no ano que vem, mesmo que a lei mude. Guardar um offset é tirar uma foto; guardar um fuso é guardar as regras que geram todas as fotos, passadas e futuras. Essa diferença é o eixo de tudo que vem a seguir.
Uma breve história do tempo coordenado
- 1884Conferência Internacional do Meridiano
Em Washington, 25 nações escolhem o meridiano de Greenwich como referência de longitude zero; o GMT vira o padrão mundial de tempo.
- 1960Coordenação internacional do tempo
Começa a coordenação mundial das transmissões de tempo e frequência, o embrião do UTC.
- 1967O segundo vira atômico
O segundo do SI passa a ser definido pelo átomo de césio; "UTC" se firma como a sigla oficial.
- 1972UTC ganha sua forma atual
O UTC passa a andar em passos de 1 segundo inteiro sobre o TAI; o primeiro segundo bissexto é inserido em 30 de junho de 1972.
- Anos 1980Nasce o banco de fusos
Surge o banco de dados de fusos (tz / zoneinfo), que reúne a história local de cada região e hoje é mantido pela IANA.
- 2019Brasil encerra o horário de verão
O Decreto nº 9.772, de 25 de abril de 2019, revoga o horário de verão; o último período aplicado havia terminado em fevereiro de 2019.
- 2022A aposentadoria do segundo bissexto
A Resolução 4 da 27ª CGPM decide deixar a diferença UT1−UTC crescer: os segundos bissextos serão descontinuados até, no máximo, 2035.
O UTC é o TAI acrescido de um número inteiro de segundos bissextos, inseridos de forma irregular para manter o relógio civil dentro de cerca de 0,9 segundo da rotação real da Terra (o UT1). Como a Terra não gira num ritmo previsível, esses saltos nunca puderam ser agendados com anos de antecedência, o que atormenta qualquer sistema que assuma que todo minuto tem exatamente 60 segundos. Foi por isso que a Conferência Geral de Pesos e Medidas (CGPM) decidiu, em 2022, parar de inserir segundos bissextos até 2035, aceitando que o UTC se afaste um pouco mais da rotação terrestre em troca de previsibilidade.
O banco IANA e por que America/Sao_Paulo
Todo sistema operacional, linguagem e runtime consulta a mesma fonte da verdade sobre fusos: o banco de dados IANA (também chamado tz, zoneinfo ou banco de Olson). Seus identificadores seguem o padrão Área/Local, um continente ou oceano mais a maior cidade representativa: America/Sao_Paulo, Europe/London, Asia/Tokyo. Por que a cidade e não "BRT"? Porque a sigla é ambígua (BST é British Summer Time ou Bangladesh Standard Time?) e, pior, ela codifica o offset atual, que muda. Um nome de cidade é politicamente estável e permite ao banco anexar a ele todo o histórico e as regras futuras da região. Quando um governo muda as regras, como o Brasil fez em 2019, sai uma nova versão do tzdata e cada sistema atualizado aprende o novo comportamento. As versões não têm calendário fixo: saem quando a política obriga, muitas vezes várias vezes por ano, nomeadas como 2025a, 2025b, e assim por diante.
Um exemplo torna a diferença entre offset e fuso concreta. São Paulo (America/Sao_Paulo) está hoje em UTC−3 o ano inteiro, pois não tem mais horário de verão. Nova York (America/New_York) alterna: UTC−4 no verão do Hemisfério Norte (EDT) e UTC−5 no inverno (EST). Marque uma call recorrente "às 9h em São Paulo" e veja o que acontece com o relógio de Nova York conforme a estação:
| Data | São Paulo (UTC−3) | Em UTC | Nova York |
|---|---|---|---|
| 15 jul 2025 | 09:00 | 12:00 | 08:00 (EDT, UTC−4) |
| 15 jan 2025 | 09:00 | 12:00 | 07:00 (EST, UTC−5) |
O passo do meio é sempre o mesmo: 09:00 em São Paulo é 09:00 + 3 = 12:00 UTC nos dois dias. O que muda é a volta: em julho, Nova York está a −4 do UTC, então 12:00 − 4 = 08:00; em janeiro, está a −5, então 12:00 − 5 = 07:00. A diferença entre as duas cidades é de 1 hora no verão do Norte e de 2 horas no inverno. Se você tivesse guardado apenas o offset da primeira medição, a segunda sairia errada. Converta qualquer par de cidades no conversor de fuso horário abaixo.
ISO 8601, RFC 3339 e o instante no fio
Para trafegar entre sistemas, um horário precisa nomear um instante sem ambiguidade, e isso exige uma referência de fuso. O ISO 8601 é o padrão de formato de data e hora; o RFC 3339 é o perfil enxuto dele para a internet, adotado em APIs, logs e JSON. Uma string só é um instante se carregar um offset ou o sufixo Z. Veja as partes:
2025-07-15T09:00:00-03:00 <- RFC 3339 / ISO 8601
2025-07-15 date (ano-mes-dia / year-month-day)
T separator between date and time
09:00:00 local time (hh:mm:ss)
-03:00 offset from UTC (3 h behind)
= 2025-07-15T12:00:00Z same instant; Z = UTC = +00:00Aqui mora a razão de offset ≠ fuso: da string 2025-07-15T09:00:00−03:00 você sabe o instante, mas não sabe as regras. Não dá para dizer se esse relógio marcará −03:00 em janeiro, porque você não sabe se é São Paulo (offset fixo) ou um fuso com horário de verão. Um offset é um fato sobre um único momento; um fuso é o livro de regras que projeta o futuro. Por isso, para reconstruir horários locais futuros, você precisa do identificador IANA, não de um número.
Segundo exemplo, agora partindo de um timestamp Unix, os segundos decorridos desde 1970-01-01T00:00:00Z. Um log registra o valor 1 700 000 000. Convertendo, chegamos a 2023-11-14T22:13:20Z. Esse instante é único; o que muda é o relógio de parede em cada lugar:
Repare que em Tóquio a data avança para 15 de novembro: somar 9 horas a 22:13 estoura a meia-noite. É o mesmo instante, 1 700 000 000 no fio, visto por três relógios. Leia qualquer timestamp Unix no conversor de timestamp e faça aritmética de duração no calculador de horas.
E o problema do ano 2038?
Sistemas que guardam o tempo Unix em um inteiro de 32 bits com sinal só chegam até 2 147 483 647 (2³¹ − 1) segundos após a época. Esse limite é atingido às 03:14:07 UTC de 19 de janeiro de 2038; no segundo seguinte, o contador transborda e "volta" para 20:45:52 UTC de 13 de dezembro de 1901.
A correção é armazenar em 64 bits, o que empurra o estouro para daqui a bilhões de anos, ou usar uma string ISO 8601. Vale auditar embarcados e sistemas legados que raramente são atualizados; são os mais expostos.
Horários que não existem e que acontecem duas vezes
Onde ainda há horário de verão, cada transição cria uma anomalia no relógio local. Nos Estados Unidos, a regra em vigor desde 2007 é: avança na segunda hora da manhã do segundo domingo de março e recua na primeira hora da manhã do primeiro domingo de novembro. Em 2025, isso caiu em 9 de março e 2 de novembro. Nessas duas datas, o horário local deixa de ser uma linha contínua.
| Transição | O que acontece com o relógio | Exemplo (2025) |
|---|---|---|
| Primavera pra frente | Salta de 02:00 direto para 03:00; a hora entre elas não existe. | 09 mar: 02:30 nunca acontece. |
| Outono pra trás | Volta de 02:00 para 01:00; a hora entre elas ocorre duas vezes. | 02 nov: 01:30 acontece duas vezes. |
As consequências são práticas e desagradáveis. Um agendamento marcado para 02:30 no dia da virada de primavera pode nunca disparar; no dia da virada de outono, pode disparar duas vezes. A string "2025-11-02 01:30" em America/New_York é genuinamente ambígua, corresponde a dois instantes UTC diferentes (um ainda em EDT, outro já em EST), e o parser precisa de uma regra para escolher. É exatamente por isso que agendadores baseados em horário de parede exigem cuidado nas transições; se você define tarefas com expressões cron, teste o comportamento delas nesses dois dias do ano.
A regra de ouro de armazenamento
Junte tudo e a estratégia de armazenamento se resolve sozinha. Existem dois modelos, e a escolha entre eles decide se seu sistema sobrevive a uma mudança de lei. Guarde o instante em UTC mais o fuso IANA, ou guarde o horário local mais um offset, mas os dois não são intercambiáveis:
Guardar UTC + fuso IANA
- O instante em UTC nunca muda de significado, mesmo se a lei do fuso mudar.
- O identificador (America/Sao_Paulo) reconstrói o horário local certo em qualquer data.
- A exibição vira um cálculo; o dado guardado é canônico e à prova de futuro.
Guardar horário local + offset
- O offset congela uma foto: se a regra mudar, o horário recalculado sai errado.
- Não distingue os dois "01:30" do outono; é ambíguo por construção.
- Serve só para registrar o que um relógio marcou naquele instante, não para agendar o futuro.
- Guarde instantes (logs, "criado em", "pago em") em UTC, de preferência como timestamp with time zone ou string ISO 8601 com Z.
- Guarde o identificador de fuso IANA (America/Sao_Paulo), não o offset, quando o evento for futuro e recorrente.
- Nunca guarde apenas o offset (−03:00) para um evento futuro: ele não reconstrói regras que ainda podem mudar por lei.
- Use o fuso do usuário só na camada de exibição; converta na borda e mantenha UTC no centro.
- Teste o sistema exatamente nas transições de horário de verão, a hora que não existe e a que acontece duas vezes.
- Prefira 64 bits (ou string ISO) a segundos Unix de 32 bits, para não esbarrar no estouro de 2038.
Perguntas frequentes
UTC e GMT são a mesma coisa?
Devo guardar datas em UTC ou no horário local?
Por que usar America/Sao_Paulo em vez de "BRT" ou −03:00?
O que é o problema do ano 2038?
O Brasil ainda tem horário de verão?
UTC é a régua, o offset é uma foto e o fuso IANA é o livro de regras. Guarde instantes em UTC, guarde America/Sao_Paulo (não −03:00) quando o evento é futuro e recorrente, e nunca reduza um compromisso recorrente a um único instante. Teste seu código nas transições de horário de verão, na hora que não existe e na que acontece duas vezes, e as datas param de quebrar em produção.
Fontes e referências
- RFC 3339, Date and Time on the Internet: Timestamps
- IANA, Time Zone Database (tz / zoneinfo)
- BIPM, Resolução 4 da 27ª CGPM (2022), sobre o futuro do UTC
- Câmara dos Deputados, Decreto nº 9.772, de 25 de abril de 2019
- The Open Group, POSIX, “Seconds Since the Epoch” (§4.16)
- Atas da Conferência Internacional do Meridiano (Washington, 1884)