Como Converter Entre Fusos Horários
A conversão de fuso horário falha de duas formas: offset errado ou ignorar o horário de verão (DST). Nova York é UTC−5 no inverno e UTC−4 no verão. "17h EST" em fevereiro usa um offset UTC diferente de "17h EDT" em julho. Ferramentas e código que fixam offsets erram.
No navegador
Insira um horário e escolha dois fusos no Time Zone Converter para ver o equivalente. O conversor usa dados de fuso IANA, então as transições de horário de verão são tratadas automaticamente — sem ajuste manual de offset.
Offsets UTC para fusos comuns
| Cidade | Fuso IANA | Offset padrão | Offset DST |
|---|---|---|---|
| Nova York | America/New_York | UTC−5 | UTC−4 |
| Londres | Europe/London | UTC+0 | UTC+1 |
| Paris | Europe/Paris | UTC+1 | UTC+2 |
| Dubai | Asia/Dubai | UTC+4 | — (sem DST) |
| Mumbai | Asia/Kolkata | UTC+5:30 | — (sem DST) |
| Singapura | Asia/Singapore | UTC+8 | — (sem DST) |
| Tóquio | Asia/Tokyo | UTC+9 | — (sem DST) |
| Sydney | Australia/Sydney | UTC+10 | UTC+11 |
| São Paulo | America/Sao_Paulo | UTC−3 | UTC−2 |
Use nomes de fuso IANA (America/New_York), não abreviações (EST). EST é ambíguo — refere-se a fusos diferentes na América do Norte e na Austrália.
Python
Python 3.9+ inclui zoneinfo na biblioteca padrão. Nenhum pacote de terceiros necessário.
from datetime import datetime
from zoneinfo import ZoneInfo
# Criar um datetime com informação de fuso horário
ny_time = datetime(2026, 3, 15, 14, 30, tzinfo=ZoneInfo('America/New_York'))
# Converter para outros fusos
london = ny_time.astimezone(ZoneInfo('Europe/London'))
tokyo = ny_time.astimezone(ZoneInfo('Asia/Tokyo'))
print(f'Nova York: {ny_time:%Y-%m-%d %H:%M %Z}')
print(f'Londres: {london:%Y-%m-%d %H:%M %Z}')
print(f'Tóquio: {tokyo:%Y-%m-%d %H:%M %Z}')
# Converter o horário UTC atual para vários fusos
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
now_utc = datetime.now(timezone.utc)
zones = ['America/Sao_Paulo', 'America/New_York', 'Europe/London', 'Asia/Tokyo']
for tz in zones:
local = now_utc.astimezone(ZoneInfo(tz))
print(f'{tz:<25} {local:%Y-%m-%d %H:%M %Z}')
JavaScript
// Converter uma data para um fuso horário específico
function convertToTimezone(date, timezone) {
return new Intl.DateTimeFormat('pt-BR', {
timeZone: timezone,
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false,
}).format(date);
}
const now = new Date();
console.log(convertToTimezone(now, 'America/Sao_Paulo'));
console.log(convertToTimezone(now, 'America/New_York'));
console.log(convertToTimezone(now, 'Asia/Tokyo'));
// Obter o offset UTC atual (em minutos) para qualquer fuso
function getUtcOffsetMinutes(timezone, date = new Date()) {
const utc = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));
const tz = new Date(date.toLocaleString('en-US', { timeZone: timezone }));
return (tz - utc) / 60000;
}
console.log(getUtcOffsetMinutes('America/Sao_Paulo')); // -180 ou -120 dependendo do horário de verão
console.log(getUtcOffsetMinutes('Asia/Tokyo')); // sempre 540
A armadilha do datetime sem fuso
Um datetime Python sem informação de fuso é ingênuo (naive) — não tem conceito de DST. Aritmética em datetimes ingênuos produz resultados errados em transições de horário de verão.
from datetime import datetime, timedelta
# Errado — datetime ingênuo no dia de mudança do horário de verão dos EUA (relógios adiantam às 2h)
dt = datetime(2026, 3, 8, 1, 0)
print(dt + timedelta(hours=2)) # Mostra 3:00 AM, mas o horário local saltou para 3 AM às 2 AM
# Correto — datetime com fuso horário
from zoneinfo import ZoneInfo
dt = datetime(2026, 3, 8, 1, 0, tzinfo=ZoneInfo('America/New_York'))
print(dt + timedelta(hours=2)) # Contabiliza corretamente a lacuna do DST
Sempre anexe um fuso ao criar um datetime sobre o qual fará aritmética.
Armazenar e transmitir horários
| Abordagem | Problema |
|---|---|
Armazenar como EST / PST |
Abreviação ambígua, DST não codificado |
Armazenar como offset UTC (-05:00) |
Não codifica o comportamento DST futuro |
| Armazenar como UTC + nome de fuso IANA | Correto — sem ambiguidade, DST tratado |
Para bancos de dados: armazene o timestamp UTC. Armazene o nome do fuso IANA separadamente se precisar exibir horário local. Reconstrua o horário local na leitura.
Pontos principais
- Use nomes de fuso IANA (
America/New_York) — abreviações comoESTsão ambíguas entre continentes. zoneinfodo Python 3.9+ trata DST automaticamente; não precisa depytzem projetos modernos.- Datetimes ingênuos produzem resultados errados nos limites de DST — sempre anexe um fuso.
- Dubai, Mumbai, Singapura e Tóquio não têm DST — o offset é constante o ano todo.
- Armazene timestamps como UTC no banco; reconstrua o horário local com o nome IANA na exibição.