Qualquer sistema que armazena um momento no tempo acaba fazendo a mesma pergunta: este número está em segundos ou em milissegundos? Timestamps Unix parecem triviais — um inteiro que conta os segundos desde 1º de janeiro de 1970 — e é exatamente por isso que são tratados da errada. Um valor errado por um fator de 1000, uma data em 1970, um deslocamento de fuso que só aparece em usuários do outro hemisfério: tudo vem dos mesmos poucos mal-entendidos.
Este artigo explica o que um timestamp Unix mede de verdade, como distinguir segundos de milissegundos, como o ISO 8601 entra na conversa e como converter entre formatos sem adivinhar.
O que um timestamp Unix realmente é
Um timestamp Unix — também chamado de época — é o número de segundos decorridos desde as 00:00:00 UTC de 1º de janeiro de 1970, a época Unix. É um inteiro sem informação de fuso: o mesmo número descreve o mesmo instante em qualquer lugar do planeta.
Por não carregar fuso, a época é um formato de troca natural para máquinas. APIs, logs, bancos de dados e filas de mensagens armazenam timestamps; humanos leem datas. A conversão entre os dois mundos é onde moram os erros.
Repare no que um timestamp não contém: fuso horário, locale ou calendário. 1758537600 é um instante. Que alguém em Singapura veja 21:00 e alguém em Lisboa veja 14:00 depende só de como você apresenta o valor.
Segundos vs. milissegundos: o erro mais comum
Duas convenções convivem e ambas estão em toda parte:
- Segundos — hoje 10 dígitos, por exemplo
1758537600. O Unix tradicional,Unix()do Go,getEpochSecond()do Java, Redis e a maioria dos bancos de dados usam essa unidade. - Milissegundos — 13 dígitos, por exemplo
1758537600000.Date.now()do JavaScript,getTime()do Java e a maioria das APIs de navegador usam essa unidade.
Confundir a unidade faz a data pular para 1970 ou 2286. Não existe uma regra universal para detectar a unidade, então o caminho confiável é conhecer o contrato da fonte. Se você tiver que adivinhar, 10 dígitos costumam ser segundos e 13 costumam ser milissegundos — mas adivinhar é o erro, não a solução.
Regra: guarde a unidade junto com o valor. Use um nome de coluna (created_at_ms), um campo explícito da API ou uma propriedade unit. Qualquer coisa é melhor que um inteiro nu chamado time.
ISO 8601: o lado legível por humanos
Strings ISO 8601 são o contraponto dos números de época: legíveis, ordenáveis em UTC e não ambíguas quando carregam um deslocamento.
2026-09-22T14:00:00Z # UTC, indicado pelo Z final
2026-09-22T14:00:00+02:00 # o mesmo instante, hora local de Berlim
2026-09-22T14:00:00.123Z # preserva os milissegundos
O Z final e o deslocamento numérico não são enfeite. Sem um dos dois, a string não tem fuso e o seu código tem de adivinhar — e é assim que “a mesma hora” vira silenciosamente um erro de três horas.
Fusos horários e UTC
Armazene e compare em UTC, e converta para um fuso local na camada de apresentação, apenas quando for exibir para uma pessoa.
const now = Date.now(); // milissegundos desde a época
const seconds = Math.floor(now / 1000); // segundos desde a época
new Date(seconds * 1000).toISOString(); // "2026-09-22T14:00:00.000Z"
Duas regras evitam a maioria dos problemas de fuso:
- Nunca compare uma hora local ingênua com outra. Serialice ambas em instantes primeiro e compare depois.
- Guarde o deslocamento junto com o valor quando o fuso do usuário importa (compromissos, horários, períodos de faturamento). Um instante em UTC mais um identificador IANA como
Europe/Lisboné melhor que um deslocamento fixo, porque deslocamentos fixos mudam com o horário de verão.
Guia de conversão
| Converter | JavaScript | Python |
|---|---|---|
| Milissegundos para string de data | new Date(1758537600000).toISOString() |
datetime.fromtimestamp(1758537600, tz=timezone.utc) |
| String de data para segundos | Math.floor(Date.parse(s) / 1000) |
int(dt.replace(tzinfo=timezone.utc).timestamp()) |
| Segundos para milissegundos | seconds * 1000 |
seconds * 1000 |
| Hora atual | Date.now() (milissegundos) |
int(time.time()) (segundos) |
Repare que Date.now() devolve milissegundos enquanto time.time() devolve segundos — uma ilustração compacta de que a unidade é uma convenção por linguagem, não um padrão universal.
Erros para evitar
- Multiplicar por 1000 “por garantia”. Decida pelo contrato, nunca pelo tamanho do número.
- Armazenar hora local sem deslocamento. O horário de verão quebra a aritmética mais cedo ou mais tarde.
- Fazer parse fatiando strings. Use o analisador da biblioteca padrão: o ISO 8601 traz semana da data, formato abreviado e frações que quebram código caseiro.
- Formatos de data dentro do SQL. Mantenha o valor numérico ou em UTC no banco e formate na aplicação, onde você controla locale e fuso.
- Usar o timestamp completo como identificador humano. Quem lê em voz alta deixa cair dígitos. Arredonde ou faça hash se precisar de uma referência curta.
Experimente
Cole um valor de época ou uma string de data em um conversor de timestamps para alternar entre segundos, milissegundos, ISO 8601 e a sua hora local. A conversão acontece no navegador, então nenhum timestamp — sensível ou não — precisa sair do seu dispositivo para ser legível.