0Pricing
SQL Academy · Aula

Fusos horários: TIMESTAMP em comparação com TIMESTAMPTZ

Entenda a diferença entre TIMESTAMP e TIMESTAMPTZ, faça conversões com AT TIME ZONE e armazene em UTC para aplicações portáveis.

Fusos horários: TIMESTAMP em comparação com TIMESTAMPTZ é uma aula grátis de SQL Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Academy inclui 4 aulas no total.

Dois tipos de marca de tempo

O PostgreSQL tem DOIS tipos de marca de tempo:

  • TIMESTAMP — marca de tempo «ingênua», sem informação de fuso
  • TIMESTAMPTZ — marca de tempo com fuso horário (armazenada internamente como UTC)

Regra geral: prefira TIMESTAMPTZ para eventos; use TIMESTAMP para horários puramente abstratos, como «09:00 no horário comercial».

Como TIMESTAMPTZ funciona

Internamente, é sempre armazenado como UTC. No INSERT, sua entrada é convertida do TZ da sessão para UTC. No SELECT, a saída é convertida de volta para o TZ da sessão.

SET TIME ZONE 'Europe/Berlin';
INSERT INTO events (ts) VALUES ('2024-03-15 12:00:00');
-- stored as 2024-03-15 11:00:00 UTC (Berlin is UTC+1 in winter)

SET TIME ZONE 'UTC';
SELECT ts FROM events;
-- 2024-03-15 11:00:00+00

TIMESTAMP perde informação

Um TIMESTAMP simples não conhece o fuso. «2024-03-15 12:00:00» pode representar qualquer hora local. Quando os usuários mudam de fuso, o significado se perde.

AT TIME ZONE

Converta entre fusos para exibição:

SELECT ts AT TIME ZONE 'America/New_York' AS ny_time FROM events;
SELECT ts AT TIME ZONE 'Asia/Tokyo'        AS tokyo_time FROM events;

Armazenando UTC e exibindo a hora local

Prática recomendada: armazene TIMESTAMPTZ e converta para o fuso do usuário no SELECT, nunca o contrário.

SELECT id,
       ts AT TIME ZONE COALESCE(u.tz, 'UTC') AS local_ts
FROM events e
JOIN users u ON u.id = e.user_id;

SESSION TIME ZONE

Você pode defini-lo por sessão, por usuário ou globalmente:

-- Session:
SET TIME ZONE 'Europe/Berlin';

-- Per-user (PG):
ALTER ROLE alice SET timezone TO 'Europe/Berlin';

-- Server default in postgresql.conf:
-- timezone = 'UTC'

SUPPLY ZONE WITH LITERAL

Incorpore um fuso no literal:

SELECT TIMESTAMPTZ '2024-03-15 12:00:00 Europe/Berlin';
SELECT '2024-03-15 12:00:00+02'::TIMESTAMPTZ;

NOW() retorna TIMESTAMPTZ

NOW() e CURRENT_TIMESTAMP sempre retornam TIMESTAMPTZ. Misturá-los com colunas TIMESTAMP é um erro comum.

Quando TIMESTAMP (sem fuso) é a escolha certa

Para horários abstratos ou locais que realmente não dependem de um fuso — «a loja abre às 09:00» — use TIMESTAMP (ou TIME).

CREATE TABLE store_hours (
  store_id BIGINT,
  open_at  TIME NOT NULL,
  close_at TIME NOT NULL
);

Transições de DST

TIMESTAMPTZ lida automaticamente com DST. Adicionar INTERVAL funciona em horas do relógio de parede, a menos que você atravesse o limite de DST — nesse caso, o deslocamento pode ser de 23 ou 25 horas.

SELECT TIMESTAMPTZ '2024-03-30 23:00:00 Europe/Berlin' + INTERVAL '5 hours';
-- Result accounts for the DST transition on March 31

Não armazene deslocamentos; armazene nomes de fusos

Um deslocamento como +02:00 não informa quando o DST começa. Um nome de fuso como Europe/Berlin informa. Ao armazenar o fuso residencial de um usuário, armazene o nome IANA.

Revisão

Use TIMESTAMPTZ por padrão para eventos.

  • Armazenado como UTC, exibido no TZ da sessão
  • Converta para exibição com AT TIME ZONE
  • Use TIMESTAMP (sem fuso) apenas para horários locais abstratos

Verificação rápida

Você está desenvolvendo um SaaS global que registra eventos dos usuários. Qual tipo de marca de tempo deve usar na coluna occurred_at?

Perguntas Frequentes

A aula “Fusos horários: TIMESTAMP em comparação com TIMESTAMPTZ” é grátis?

Sim — o texto completo de “Fusos horários: TIMESTAMP em comparação com TIMESTAMPTZ” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Academy, atualize para CoddyKit PRO. O curso de SQL Academy inclui 4 aulas no total.

O que vou aprender em “Fusos horários: TIMESTAMP em comparação com TIMESTAMPTZ”?

Entenda a diferença entre TIMESTAMP e TIMESTAMPTZ, faça conversões com AT TIME ZONE e armazene em UTC para aplicações portáveis. Você pratica SQL Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar SQL Academy?

Nenhuma experiência prévia é necessária. SQL Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Fusos horários: TIMESTAMP em comparação com TIMESTAMPTZ”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de SQL Academy?

Sim. Cada aula de SQL Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Aritmética de datas e INTERVAL
  2. EXTRACT, DATE_TRUNC, AGE
  3. Fusos horários: TIMESTAMP em comparação com TIMESTAMPTZ
  4. Relatórios comuns de datas (MTD, WoW, YoY)
← Voltar para SQL Academy