Fusos horários sem susto — UTC, offsets e horário de verão
A diferença entre fuso horário e offset UTC, por que a distância entre duas cidades muda durante o ano e como guardar e converter horários com segurança.
Por Felipe YamaokaPublicado em 5 de novembro de 20266 min de leitura
A reunião que mudou sozinha
Um time em São Paulo marca uma call semanal com um cliente em Nova York: 10:00 em São Paulo, 8:00 em Nova York. Em julho o cliente entra uma hora atrasado, e ninguém mexeu no convite. Em março o problema volta, no sentido contrário. Nada quebrou na agenda. O que mudou foi o relógio de Nova York.
Fuso horário parece simples até você precisar acertar em qualquer data. Este guia explica o vocabulário, por que a diferença entre duas cidades não é fixa e as poucas regras que evitam a maioria dos bugs no código.
UTC, offset e fuso horário são coisas diferentes
Três termos costumam ser usados como sinônimos, e não são:
- UTC (Tempo Universal Coordenado) é o relógio de referência. Ele nunca muda por horário de verão e é o que servidores, logs e timestamps deveriam usar.
- Offset é uma distância fixa do UTC num determinado momento, escrita como
UTC−3,-03:00ouUTC+5:30. - Fuso horário é uma região com um histórico de regras, identificada por um nome IANA como
America/Sao_Paulo,America/New_YorkouEurope/Lisbon. As regras dizem qual offset vale em cada data.
A ideia central: fuso não é offset. America/New_York é UTC−5 em janeiro e UTC−4 em julho. Se você guardar "Nova York = −5", metade do ano fica errada.
A base de fusos da IANA, também chamada de tzdata, é mantida por voluntários e atualizada várias vezes por ano, porque governos mudam as regras. O Brasil, por exemplo, acabou com o horário de verão em 2019. Desde então America/Sao_Paulo é UTC−3 o ano inteiro, mas uma data de 2018 continua usando as regras antigas, quando São Paulo ficava em UTC−2 no verão. Navegadores, sistemas operacionais e linguagens trazem uma cópia dessa base, e é por isso que você deve sempre se referir aos fusos pelo nome IANA, e não por siglas.
Por que as siglas são uma armadilha
EST, CST e IST parecem práticas, mas são ambíguas. CST pode ser o horário central dos Estados Unidos (UTC−6), o horário da China (UTC+8) ou o de Cuba (UTC−5). IST é usada na Índia, na Irlanda e em Israel. E a sigla descreve só uma estação: escrever "9:00 EST" para uma data de julho está simplesmente errado, porque nessa época Nova York está em EDT.
Use o nome IANA nos dados e no código, e mostre siglas só como rótulo para pessoas, se for o caso.
O horário de verão muda a distância entre cidades
O horário de verão adianta os relógios na primavera e atrasa no outono, mas cada país faz isso numa data diferente, e muitos não fazem. O resultado é que a diferença entre duas cidades muda ao longo do ano.
Alguns números reais de 2026:
- São Paulo e Nova York: 2 horas de diferença em janeiro e 1 hora em julho, porque só Nova York mexe no relógio.
- São Paulo e Lisboa: 3 horas em janeiro e 4 horas em julho.
- Nova York e Londres: normalmente 5 horas, mas só 4 entre 8 e 29 de março e entre 25 de outubro e 1º de novembro, porque Estados Unidos e Reino Unido trocam o horário em domingos diferentes.
- Sydney fica no hemisfério sul, então está em
UTC+11em janeiro eUTC+10em julho, ao contrário da Europa.
Os offsets também nem sempre são horas cheias: a Índia é UTC+5:30, o Nepal é UTC+5:45 e as Ilhas Chatham, na Nova Zelândia, ficam em UTC+12:45 no inverno e UTC+13:45 no verão.
Por isso um conversor precisa usar as regras da data escolhida, e não as de hoje. O Conversor de Fuso Horário deste site faz exatamente isso: meio-dia em São Paulo em 1º de julho de 2026 é 11:00 em Nova York, 16:00 em Londres e já 00:00 do dia 2 em Tóquio.
Horários que não existem e horários que acontecem duas vezes
O horário de verão cria duas situações estranhas por ano em cada fuso que o adota.
A hora pulada. Em 8 de março de 2026, os relógios de Nova York pulam de 01:59 direto para 03:00. Um horário como 02:30 nesse dia nunca acontece. As bibliotecas tratam isso de jeitos diferentes: algumas dão erro, outras avançam. O conversor deste site leva o horário para o primeiro válido, 03:30.
A hora repetida. Em 1º de novembro de 2026, os relógios de Nova York voltam de 01:59 para 01:00. O intervalo de 01:00 a 01:59 acontece duas vezes, primeiro em UTC−4 e depois em UTC−5. Um horário local como 01:30 nesse dia é ambíguo; você precisa do offset para saber qual dos dois é.
Quem viveu o horário de verão brasileiro lembra do mesmo efeito: na virada, sistemas que agendavam tarefas à meia-noite rodavam duas vezes ou não rodavam. Se a sua aplicação agenda tarefas em horário local, evite a janela entre 01:00 e 03:00 quando puder e teste essas datas de propósito.
Regras para o código
A maioria dos bugs de fuso some com alguns hábitos:
- Guarde instantes em UTC. No banco, use um tipo que representa um instante, como
timestamptzno PostgreSQL, ou um timestamp Unix. Nunca guarde horário local sem o fuso. - Guarde o fuso separado quando ele importar. Uma reunião recorrente "toda segunda às 10:00 em São Paulo" precisa de
America/Sao_Paulo, e não de um offset fixo, para que as datas futuras sigam as regras futuras. - Converta nas pontas. Leia e grave UTC no sistema inteiro e converta para o horário local só na hora de mostrar a data para uma pessoa, no fuso dela.
- Use a base de fusos da plataforma. No JavaScript,
Intl.DateTimeFormatcom a opçãotimeZone. No Python, o módulozoneinfo. No Java,java.time.ZonedDateTime. Não escreva offsets fixos no código. - Envie ISO 8601 com offset ou
Z.2026-07-01T15:00:00Ze2026-07-01T12:00:00-03:00são o mesmo instante e não deixam dúvida.2026-07-01 12:00deixa.
Um exemplo mínimo em JavaScript, mostrando o mesmo instante em vários fusos:
const instant = new Date("2026-07-01T15:00:00Z");
for (const timeZone of ["America/Sao_Paulo", "America/New_York", "Asia/Tokyo"]) {
const time = new Intl.DateTimeFormat("pt-BR", {
timeZone,
dateStyle: "medium",
timeStyle: "short",
}).format(instant);
console.log(timeZone, time);
}
// America/Sao_Paulo 1 de jul. de 2026, 12:00
// America/New_York 1 de jul. de 2026, 11:00
// Asia/Tokyo 2 de jul. de 2026, 00:00E a mesma ideia em Python:
from datetime import datetime
from zoneinfo import ZoneInfo
meeting = datetime(2026, 7, 1, 12, 0, tzinfo=ZoneInfo("America/Sao_Paulo"))
print(meeting.astimezone(ZoneInfo("Europe/Lisbon")))
# 2026-07-01 16:00:00+01:00Erros comuns
- Tratar offset como fuso.
-05:00só está certo para Nova York numa parte do ano. - Usar siglas como identificador.
CSTeISTsignificam coisas diferentes em cada país. - Calcular com as regras de hoje. Uma reunião em julho precisa dos offsets de julho.
- Somar 24 horas para ter "amanhã no mesmo horário". No dia da troca do horário de verão, o dia tem 23 ou 25 horas. Some um dia de calendário no fuso, e não 24 horas.
- Confiar no horário local do servidor. Servidores deveriam rodar em UTC; nunca deixe o fuso da máquina vazar para os dados gravados.
- Esquecer que a base muda. Mantenha o runtime e a tzdata atualizados, porque as regras mudam todo ano em algum lugar.
Resumo
UTC é a referência, offset é a distância do UTC num momento e fuso horário é um conjunto de regras que decide qual offset vale em cada data. Como o horário de verão começa e termina em datas diferentes pelo mundo, a distância entre duas cidades muda durante o ano, e alguns horários locais são pulados ou repetidos. Guarde instantes em UTC, guarde o nome IANA do fuso quando o horário local importar e converta com as regras da data de verdade.
Leia também
Base64 não é criptografia — o que é, quando usar e a variante URL-safe
Como o Base64 transforma bytes em texto, por que ele não esconde nada, como tratar acentos e emoji do jeito certo e quando usar o alfabeto URL-safe.
5 de novembro de 20265 min de leituraFerramenta: Codificador/Decodificador Base64
A regex que trava o navegador — backtracking catastrófico explicado
Por que uma expressão regular curta pode levar segundos ou travar a página, como reconhecer quantificadores aninhados e como reescrever o padrão.
5 de novembro de 20266 min de leituraFerramenta: Testador de Regex