Anúncios incomodam? Ir Sem anúncios Hoje

Fuso Horário é uma Mentira (e Como Tratar em Código)

Publicado em

As zonas horárias parecem simples em um mapa. Elas não são. Aqui está por que elas quebram o software — e o modelo mental correto para lidar com elas no código.

Fusos horários são uma mentira (e como lidar com eles no código) 1
ANUNCIADO Remover?

Você abre um mapa. Você vê fatias verticais. "UTC-5 é Horário Oriental, UTC+1 é Horário Central Europeu". Simples, não?

Errado. Zonas horárias são uma construção política, não um fato geográfico — e essa distinção lhe salvará de algumas das piores falhas no desenvolvimento de software.

Por que Zonas Horárias São Na verdade um Desastre

Aqui está o que a base de dados tz do seu sistema operacional trata silenciosamente por você:

  • Horário de Verão (DST) — Nem todos os países o observam, os países mudam as regras e a mudança ocorre em datas diferentes dependendo do local. Os EUA mudaram a data em 2007. Egito aboliu o DST em 2011, depois o reinstaurou, depois o aboliu novamente.
  • Deslocamentos de meia-hora e de um quarto de hora — Índia (UTC+5:30), Nepal (UTC+5:45) e partes da Austrália (UTC+9:30) existem. A sua suposição de que os deslocamentos são horas inteiras está errada.
  • Mudanças históricas — A Rússia mudou de UTC+4 para UTC+3 em 2014. Samoá pulara um dia inteiro (30 de dezembro de 2011) para mudar de um lado da Linha de Data Internacional para o outro. Quando você está lidando com timestamps históricos, o deslocamento "correto" pode ser completamente diferente do que é hoje.
  • Tempos ambíguos — Quando os relógios voltam, 1:30 da manhã acontece duas vezes. Quando os relógios avançam, 2:30 da manhã não existe absolutamente. Se você armazenar "3 de novembro de 2024 às 1:45 da manhã Horário Oriental" sem um deslocamento UTC, você tem um timestamp ambíguo.

Nenhum desses detalhes é trivia. Cada um desses casos extremos causou falhas reais em produção — eventos do calendário perdidos, pagamentos duplicados, sistemas de programação quebrados.

A única regra que corrige a maioria dos problemas

Armazene e processe em UTC. Converta para horário local apenas no momento da exibição.

Essa é uma recomendação não controversa. É o consenso de todas as principais bases de dados, padrões de API e equipes de sistemas distribuídos. Se a coluna do seu banco de dados armazena 2024-11-03 06:45:00 em UTC, você sempre sabe exatamente que momento no tempo que representa — independentemente do local onde seu servidor está hospedado, do horário local do seu usuário ou se o DST ocorreu naquele dia.

O momento em que você armazena 2024-11-03 01:45:00 sem um deslocamento UTC, você perdeu informações. Você criou um timestamp que pode significar duas coisas diferentes.

Como lidar com Zonas Horárias no JavaScript

O objeto integrado do JavaScript armazena o tempo como milissegundos desde o epoch do Unix (1º de janeiro de 1970 UTC) — o que é bom. O problema é que sua API é confusa e inconsistente. Date O que evitar

O que usar em vez disso

// BAD: Parsing without explicit timezone
const d = new Date('2024-11-03 01:45:00');
// Interpreted as LOCAL time — behavior varies by environment

// BAD: Storing user-facing strings as dates
const meeting = '3:00 PM Thursday';
// This is meaningless without a timezone

Se você estiver construindo algo além de formatação simples de datas, use a

// GOOD: Always use ISO 8601 with explicit UTC offset
const d = new Date('2024-11-03T06:45:00Z'); // Z = UTC

// GOOD: Display in user's local timezone using Intl API
const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/New_York',
  dateStyle: 'full',
  timeStyle: 'short',
});
console.log(formatter.format(d)); // "Sunday, November 3, 2024 at 1:45 AM"

biblioteca. Ela tem suporte de zona horária de primeira classe, trata corretamente as transições de DST e torna a intenção do seu código clara. Luxon Como lidar com Zonas Horárias no Python

import { DateTime } from 'luxon';

// Parse an ISO string and convert to a specific zone
const utc = DateTime.fromISO('2024-11-03T06:45:00Z');
const eastern = utc.setZone('America/New_York');
console.log(eastern.toLocaleString(DateTime.DATETIME_FULL));
// "November 3, 2024, 1:45 AM EDT"

módulo distingue entre

Python’s datetime naive (sem zona horária) e aware (com zona horária) objetos de data e hora. Os datetimes naive são uma armadilha — evite-os em qualquer código que ultrapasse fronteiras de zona horária. Para versões antigas do Python ou para necessidades mais complexas de programação,

from datetime import datetime, timezone
import zoneinfo  # Python 3.9+

# BAD: naive datetime (no timezone info)
d = datetime(2024, 11, 3, 1, 45, 0)

# GOOD: always attach a timezone
d_utc = datetime(2024, 11, 3, 6, 45, 0, tzinfo=timezone.utc)

# Convert to a specific timezone
eastern = zoneinfo.ZoneInfo('America/New_York')
d_eastern = d_utc.astimezone(eastern)
print(d_eastern)  # 2024-11-03 01:45:00-05:00

python-dateutil são opções bem mantidas. O princípio-chave permanece o mesmo: trabalhe em UTC, converta na fronteira. e Seta Como lidar com Zonas Horárias em Bases de Dados

O tratamento de zonas horárias em bases de dados confunde até mesmo desenvolvedores experientes.

O PostgreSQL tem dois tipos de timestamp:

PostgreSQL

(com zona horária). Apesar do nome, timestamp aware timestamptz não armazena realmente a zona horária — converte para UTC ao escrever e converte de volta para a zona horária da sessão ao ler. Isso é o comportamento correto. Sempre use timestamptz que armazena sem contexto de zona horária — o que você coloca é o que você obtém, sem conversão. timestamptz.

-- BAD
CREATE TABLE events (created_at TIMESTAMP);

-- GOOD
CREATE TABLE events (created_at TIMESTAMPTZ);

-- Querying across timezones
SELECT created_at AT TIME ZONE 'America/New_York' FROM events;

MySQL

MySQL’s DATETIME converte para UTC ao escrever e de volta para a zona horária do servidor atual ao ler — mas é limitado a datas entre 1970 e 2038 (o overflow do timestamp do Unix). Na prática: use TIMESTAMP colunas e garanta que sua aplicação escreva valores em UTC explicitamente. DATETIME Programação em Zonas Horárias: A Armadilha Oculta

Suponha que um usuário agende uma reunião semanal recorrente para "todos os domingos às 9h horário de Nova York". Você armazena a próxima ocorrência como um timestamp em UTC. Tudo bem — até que mudanças de DST ocorram, e agora o horário UTC que você armazenou corresponde às 10h em Nova York, em vez das 9h.

A solução: não armazene timestamps absolutos futuros para eventos recorrentes. Armazene a

regra local — o identificador de zona horária + o horário local — e calcule o próximo timestamp em UTC em tempo real. Assim, o sistema recalcula corretamente após transições de DST. Nomes de Zona Horária IANA versus Deslocamentos UTC

-- Store the intent, not the absolute moment
CREATE TABLE recurring_events (
  id SERIAL PRIMARY KEY,
  timezone TEXT NOT NULL,       -- 'America/New_York'
  local_time TIME NOT NULL,     -- '09:00:00'
  recurrence TEXT NOT NULL      -- 'WEEKLY:MONDAY'
);
-- Compute next_occurrence_utc in application code at dispatch time

Quando armazene a preferência de zona horária do usuário, armazene o nome IANA (

) — não o deslocamento UTC (America/New_York, Europe/London, Asia/Kolkata). Os deslocamentos são instantâneos; os nomes IANA codificam a história completa de DST e as regras futuras.UTC-5, UTC+1no inverno e

America/New_York é UTC-5 no verão. Se você armazene UTC-4 , você está incorporando o deslocamento errado metade do ano. UTC-5Referência Rápida: As Regras

Armazene timestamps em UTC

  • — sempre, sem exceções em seu banco de dados ou respostas de API. Use nomes de zona horária IANA
  • — não deslocamentos UTC — para preferências de usuário e agendamentos recorrentes. Nunca analise strings de data sem uma zona horária explícita
  • — o comportamento implícito é dependente do ambiente. Converta para horário local na camada de exibição
  • — não em sua lógica de negócio ou consultas ao banco de dados. Para agendamentos recorrentes, armazene a regra
  • — não o horário UTC pré-calculado — para que transições de DST não corrompam as ocorrências futuras. Teste com casos extremos
  • — a hora de transição de DST, datas próximas à Linha de Data Internacional e timestamps históricos em regiões que mudaram seu deslocamento. Zonas horárias parecem simples em um mapa. Elas não são. Aqui está por que quebram software — e o modelo mental correto para lidar com elas no código.
Quer eliminar anúncios? Fique sem anúncios hoje mesmo

Instale nossas extensões

Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida

Ao Extensão do Chrome Ao Extensão de Borda Ao Extensão Firefox Ao Extensão Opera

O placar chegou!

Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!

ANUNCIADO Remover?
ANUNCIADO Remover?
ANUNCIADO Remover?

Notícias com destaques técnicos

Envolver-se

Ajude-nos a continuar fornecendo ferramentas gratuitas valiosas

Compre-me um café
ANUNCIADO Remover?