Unix Timestamps Explicados: Conversão e Armadilhas Comuns
Um Unix timestamp é um dos conceitos mais simples e, no entanto, mais mal compreendidos na programação. É o número de segundos que decorreram desde 1 de janeiro de 1970, 00:00:00 UTC — um momento conhecido como o epoch Unix. Apesar da sua simplicidade, os timestamps são uma fonte de bugs relacionados com fusos horários, precisão e overflow.
O Que É o Unix Epoch?
O Unix epoch — 1 de janeiro de 1970, 00:00:00 UTC — foi escolhido como o ponto de partida para o tempo Unix. Cada timestamp é medido em relação a este momento:
| Timestamp | Data e Hora (UTC) |
|---|---|
| 0 | 1 Jan, 1970 00:00:00 |
| 86400 | 2 Jan, 1970 00:00:00 |
| 1000000000 | 9 Set, 2001 01:46:40 |
| 1700000000 | 14 Nov, 2023 22:13:20 |
| 2000000000 | 18 Mai, 2033 03:33:20 |
Timestamps negativos representam datas anteriores ao epoch. Por exemplo, -86400 é 31 de dezembro de 1969.
Converta timestamps instantaneamente com o nosso Conversor de Timestamps.
Segundos vs. Milissegundos
Esta é a fonte de confusão mais comum. Diferentes sistemas utilizam diferentes precisões:
| Sistema | Precisão | Exemplo |
|---|---|---|
| Unix/POSIX | Segundos | 1700000000 |
| JavaScript | Milissegundos | 1700000000000 |
| Java (System.currentTimeMillis) | Milissegundos | 1700000000000 |
| Python (time.time) | Segundos (float) | 1700000000.123 |
| PostgreSQL (extract epoch) | Segundos (float) | 1700000000.123456 |
Regra prática: Se o número tem 13 dígitos, são milissegundos. Se tem 10 dígitos, são segundos.
// JavaScript returns milliseconds
const nowMs = Date.now(); // 1700000000000
const nowSec = Math.floor(nowMs / 1000); // 1700000000
Tratamento de Fusos Horários
Os Unix timestamps são sempre UTC. Não contêm informação de fuso horário. Isto é na verdade uma vantagem — fornece um ponto de referência universal.
A confusão surge ao converter timestamps para datas legíveis por humanos:
const ts = 1700000000;
const date = new Date(ts * 1000);
date.toUTCString(); // "Tue, 14 Nov 2023 22:13:20 GMT"
date.toLocaleString(); // Depends on user's local time zone
date.toISOString(); // "2023-11-14T22:13:20.000Z"
Boa prática: Armazene e transmita timestamps em UTC. Converta para hora local apenas na camada de apresentação, o mais próximo possível do utilizador.
O Problema do Ano 2038
Os sistemas Unix tradicionais armazenam timestamps como um inteiro com sinal de 32 bits. O valor máximo é 2.147.483.647, que corresponde a 19 de janeiro de 2038, 03:14:07 UTC.
Após este momento, os timestamps de 32 bits fazem overflow para valores negativos, recuando para 13 de dezembro de 1901. Isto é análogo ao bug do Y2K.
Estado atual:
- A maioria dos sistemas modernos utiliza timestamps de 64 bits (válidos até ao ano 292 mil milhões)
- O kernel Linux está limpo para timestamps de 64 bits desde a versão 5.6 (2020)
- Sistemas embebidos e bases de dados legadas permanecem em risco
- Se está a construir software que trata datas para além de 2038, verifique o seu armazenamento de timestamps
Conversão em Diferentes Linguagens
JavaScript
// Current timestamp (seconds)
const now = Math.floor(Date.now() / 1000);
// Timestamp to Date
const date = new Date(1700000000 * 1000);
// Date to timestamp
const ts = Math.floor(new Date('2023-11-14').getTime() / 1000);
Python
import time, datetime
# Current timestamp
now = int(time.time())
# Timestamp to datetime
dt = datetime.datetime.fromtimestamp(1700000000, tz=datetime.timezone.utc)
# Datetime to timestamp
ts = int(dt.timestamp())
SQL (PostgreSQL)
-- Current timestamp
SELECT EXTRACT(EPOCH FROM NOW());
-- Timestamp to date
SELECT TO_TIMESTAMP(1700000000);
-- Date to timestamp
SELECT EXTRACT(EPOCH FROM '2023-11-14'::timestamp);
Armadilhas Comuns
1. Misturar Segundos e Milissegundos
Se uma data mostra janeiro de 1970, provavelmente passou segundos onde eram esperados milissegundos (ou vice-versa). Verifique sempre qual a precisão que a API espera.
2. Ignorar Fusos Horários em Strings de Data
Fazer parsing de "2023-11-14" sem um fuso horário cria a data no fuso horário local, que varia conforme a localização do servidor. Inclua sempre o fuso horário: "2023-11-14T00:00:00Z".
3. Precisão de Vírgula Flutuante
Ao armazenar timestamps como números de vírgula flutuante, pode perder precisão para além dos milissegundos. Para precisão de microssegundos ou nanossegundos, utilize inteiros com o multiplicador apropriado.
4. Segundos Intercalares
Os Unix timestamps não contabilizam segundos intercalares. Um dia Unix é sempre exatamente 86.400 segundos, mesmo que os dias UTC reais tenham ocasionalmente 86.401 segundos. Para a maioria das aplicações, isto é irrelevante. Para aplicações científicas ou de satélite, utilize TAI (International Atomic Time) em vez disso.
ISO 8601: A Alternativa Legível por Humanos
Embora os timestamps sejam excelentes para computação, o ISO 8601 é o padrão para representação de datas legível por humanos:
2023-11-14T22:13:20Z # UTC
2023-11-14T17:13:20-05:00 # Eastern Time
2023-11-14 # Date only
A maioria das APIs deve aceitar e devolver strings ISO 8601. Utilize timestamps internamente para cálculos e armazenamento.
FAQ
Por que é que o tempo Unix começa em 1 de janeiro de 1970?
A data foi escolhida arbitrariamente quando o Unix estava a ser desenvolvido nos Bell Labs no início dos anos 1970. Era necessária uma data suficientemente recente para evitar desperdiçar bits com datas do passado distante. Como inteiros de 32 bits podem armazenar cerca de 68 anos em cada direção, começar em 1970 cobria datas de 1901 a 2038.
Devo armazenar datas como timestamps ou strings formatadas na minha base de dados?
Armazene datas como timestamps (inteiro ou tipos nativos de datetime) para ordenação, comparação e aritmética eficientes. Strings formatadas são mais difíceis de consultar e ordenar corretamente. A maioria das bases de dados tem tipos nativos de datetime que tratam isto bem. Reserve a formatação em string para exibição e respostas de API.
Recursos Relacionados
- Conversor de Timestamps — Converta entre Unix timestamps e datas legíveis por humanos
- Boas Práticas de Formatação JSON — Tratar datas em respostas JSON
- Guia UUID — Outro formato comum de identificadores com variantes baseadas em tempo