Conversor de timestamp Unix

Converta um timestamp Unix em data em qualquer fuso horário, e de volta: segundos ou milissegundos são detectados, com a forma ISO 8601 e há quanto tempo foi.

Tempo Unix atual
Detectando…
Entrada

O que é um timestamp Unix

Um timestamp Unix — também chamado tempo epoch ou tempo POSIX — é um único número que conta quantos segundos passaram desde as 00:00:00 UTC de 1 de janeiro de 1970, um instante conhecido como epoch de Unix. Por ser um só inteiro, sem fuso horário, sem calendário e sem formatação, é o formato a que os computadores recorrem sempre que um instante tem de ser armazenado, ordenado, comparado ou enviado pela rede. É o que está por trás da coluna «created_at» do seu banco de dados, dos claims «iat» e «exp» de um JWT, do mtime de um arquivo e dos timestamps de praticamente qualquer registro que venha a ler.

A contrapartida é que um número nu não diz nada a uma pessoa. 1716197600 é um instante perfeitamente válido, mas num relance não sabe se foi na terça-feira passada ou há três anos. Essa tradução, nos dois sentidos, é o que esta ferramenta faz.

Segundos ou milissegundos: a ambiguidade que morde

A convenção original do Unix conta segundos inteiros, e é isso que obtém de date +%s numa shell, de time() em PHP e de time.time() em Python depois de truncado. JavaScript, Java e muitos outros contam milissegundos: Date.now() devolve um número mil vezes maior. Ambos se chamam «timestamp», e confundi-los é um dos erros de datas mais comuns que existem.

A falha é silenciosa e não ruidosa. Leia um valor em milissegundos como segundos e a data aterra dezenas de milhares de anos no futuro; leia um valor em segundos como milissegundos e tudo se desmorona para janeiro de 1970. Nenhum dos dois lança um erro — simplesmente obtém uma data errada com todo o aspecto de ser verdadeira.

Esta ferramenta deduz pela ordem de grandeza do número e depois diz a você o que deduziu, mesmo ao lado do resultado. Os segundos epoch de hoje têm dez dígitos e os milissegundos treze, por isso o palpite está quase sempre certo — mas «quase» não chega para um valor que está prestes a colar num relatório de erro, e é por isso que a leitura está sempre visível e sempre a um clique de ser trocada.

Fusos horários, UTC e porque «local» é escorregadio

Um timestamp Unix não tem fuso horário. Identifica um instante: 1716197600 é 2024-05-20T09:33:20Z, e esse mesmo instante é simultaneamente 10:33 em Londres, 12:33 em Jerusalém e 18:33 em Tóquio, porque nesse dia Londres e Jerusalém estão no horário de verão e o Japão não adota nenhum. O fuso horário não faz parte do valor: é a lente através da qual olha para ele.

Por isso esta ferramenta mostra várias lentes ao mesmo tempo. UTC é a referência neutra em que todos os servidores e registros concordam. A sua hora local é a que o seu próprio dispositivo indica, mostrada com o nome do fuso (por exemplo Europe/Berlin) para saber sempre que lente a produziu — a detecção acontece no seu navegador, por isso quem visita de Berlim vê a hora de Berlim e quem visita de Tóquio vê a de Tóquio. A terceira linha é qualquer fuso que escolha do banco de dados IANA completo, e é a linha que quer quando está lendo o registro de um servidor que vive em outro lugar.

  • UTC — a referência em que todos os sistemas concordam, e o correto para armazenar e registrar.
  • Local — o mesmo instante tal como o seu dispositivo o vê, identificado com o fuso detectado.
  • Um fuso à sua escolha — para ler registros e rastreios de máquinas em outros locais.
  • ISO 8601 — o formato de texto de intercâmbio, p. ex. 2024-05-20T09:33:20.000Z.
  • Relativo — «há 3 horas», para ter uma noção rápida de quão recente é algo.

Os desvios são mostrados junto a cada hora (+03:00, -04:00) porque não são fixos: a maioria dos fusos desloca-se uma hora com a hora de verão, portanto o mesmo fuso pode dar desvios diferentes em alturas diferentes do ano. Uma data perto de uma mudança é precisamente onde as contas de cabeça falham.

Trabalhar com tempo epoch na prática

Cada linguagem e cada shell tem a sua maneira de produzir e ler valores epoch. Estas vale a pena memorizar:

date +%s                         # shell: hora atual em segundos
date -d @1716197600              # shell (GNU): de segundos para data
Date.now()                       # JavaScript: hora atual em MILIssegundos
new Date(1716197600 * 1000)      # JavaScript: de segundos para Date
time.time()                      # Python: segundos, como decimal
datetime.fromtimestamp(1716197600, tz=timezone.utc)
SELECT EXTRACT(EPOCH FROM now()) -- PostgreSQL: segundos

Uma regra prática que evita quase toda a dor com datas: guarde e transmita instantes em UTC — como inteiro epoch ou como cadeia ISO 8601 — e converta para um fuso local só no último momento, quando os mostra mesmo a alguém. Formatar cedo demais é como um erro de fuso horário acaba cozido dentro dos seus dados em vez de ficar na camada de apresentação.

Mais uma coisa que convém saber: um contador de segundos de 32 bits com sinal esgota-se a 19 de janeiro de 2038, o «problema do ano 2038». Os sistemas modernos usam valores de 64 bits e estão seguros, mas os dispositivos embebidos antigos e as colunas de bancos de dados herdadas são exatamente onde ainda o pode encontrar.

O que é um epoch e por que nem todo timestamp começa em 1970

Um epoch, neste sentido, é apenas um zero escolhido: o instante a partir do qual um contador é definido para começar a contar. O epoch de Unix são as 00:00:00 UTC de 1 de janeiro de 1970, e foi escolhido por ser uma data redonda e cômoda, não por derivar de alguma coisa: nada no próprio formato exige justamente esse dia. O Unix primitivo contava sessenta avos de segundo a partir de um zero muito mais próximo, e o manual da terceira edição disse sem rodeios por que aquilo não se sustentaria: trinta e dois bits de sessenta avos garantem uma crise a cada 2,26 anos, ou seja, a cada 828 dias mais ou menos. Os segundos inteiros nos mesmos trinta e dois bits chegam a cento e trinta e seis anos, ou a sessenta e oito se o contador tiver sinal, que é a data de 2038 acima.

Essa história é a razão para conferir um número longo antes de confiar nele. Outros sistemas contam a partir de outros zeros e com outras resoluções, e ler um deles como segundos Unix não deixa você errado por algumas horas: deixa você errado por séculos. Estes são os que você tem mais chance de encontrar:

  • Windows FILETIME: pulsos de cem nanossegundos desde 1 de janeiro de 1601 UTC. Divida por dez milhões e subtraia 11644473600 para obter segundos Unix; o instante 1716197600 usado ao longo de todo este guia é 133606712000000000 nesse esquema.
  • .NET DateTime.Ticks: o mesmo pulso de cem nanossegundos, mas contado do início do ano 1. O próprio epoch de Unix fica em 621355968000000000 pulsos, e é esse o número a subtrair antes de dividir.
  • A data de referência da Apple: segundos desde 1 de janeiro de 2001 UTC, usada por Cocoa e Core Data. Some 978307200 para obter segundos Unix: 1716197600 ali é 737890400.
  • Os números de série do Excel: dias em vez de segundos, contados a partir de 30 de dezembro de 1899, porque o Excel trata 1900 como ano bissexto e ele não foi.
  • O tempo GPS: segundos desde 6 de janeiro de 1980, contados sem nunca pular um segundo intercalar, de modo que o tempo GPS e o UTC já não coincidem.

Esse último aponta para algo verdadeiro sobre o próprio valor Unix: ele não é a leitura de um cronômetro. O POSIX o define como um valor que aproxima os segundos decorridos desde o epoch e exige que todo e qualquer dia seja contado com exatamente 86400 segundos, de modo que os segundos intercalares inseridos no UTC não são contados de jeito nenhum. A diferença entre dois timestamps Unix é, portanto, o número de segundos de calendário entre eles e não o número que realmente passou, e o valor se entende melhor como uma codificação de uma leitura de calendário em UTC. É também por isso que nenhum timestamp jamais nomeia um segundo intercalar: a codificação não tem lugar para um.

De uma data para um valor epoch: shell, JavaScript e Python

O bloco acima transforma um valor epoch em algo legível. O sentido inverso — uma data que você já tem, como texto ou como um conjunto de números, virando um valor epoch — é onde moram os bugs de fuso horário, porque cada um destes assume um fuso em silêncio quando o texto não nomeia nenhum. Aqui está o mesmo trabalho de três maneiras, sobre o instante 2024-05-20T09:33:20Z deste guia. As linhas de shell são o date do GNU; o date do BSD e do macOS aceita outras opções.

date -u -d '2024-05-20 09:33:20' +%s     # 1716197600 — -u lê o texto como UTC
date -d '2024-05-20 09:33:20 UTC' +%s    # o mesmo, com o fuso nomeado dentro do texto
date -d '2024-05-20 09:33:20' +%s        # nenhum dos dois: o fuso da sua máquina
Date.parse('2024-05-20T09:33:20Z') / 1000    // 1716197600 — é o Z que faz disso UTC
new Date('2024-05-20T09:33:20Z').getTime()   // o mesmo instante em milissegundos
Date.parse('2024-05-20 09:33:20')            // sem Z: o fuso da sua máquina, outro instante
from datetime import datetime, timezone
int(datetime(2024, 5, 20, 9, 33, 20, tzinfo=timezone.utc).timestamp())   # 1716197600 — datetime ciente do fuso
int(datetime.fromisoformat('2024-05-20T09:33:20+00:00').timestamp())     # o mesmo, lido de uma cadeia
int(datetime(2024, 5, 20, 9, 33, 20).timestamp())                        # ingênuo: o fuso da sua máquina

O padrão é idêntico nos três: nomeie o fuso, ou você herda aquele em que a máquina está configurada. Um número certo no seu notebook e errado por horas no de um colega é quase sempre isso, e é por isso que a ferramenta acima mostra UTC e a sua leitura local lado a lado em vez de escolher uma por você. Se você já tem o número e quer conferir a olho, cole-o no campo no topo desta página.

Perguntas frequentes

Como sabe se o meu número está em segundos ou milissegundos?
Pela sua ordem de grandeza: valores abaixo de cerca de 1e11 são lidos como segundos e os maiores como milissegundos. Hoje isso separa de forma limpa os segundos de dez dígitos dos milissegundos de treze. A leitura é mostrada ao lado do resultado e pode trocá-la com um clique, por isso a dedução nunca lhe é escondida.
Que fuso horário conta como «local»?
O que o seu próprio dispositivo indica, detectado no navegador e mostrado pelo nome para não restarem dúvidas. É o seu fuso, não o do site: quem visita de Berlim vê a hora de Berlim e quem visita de Tóquio vê a de Tóquio.
Posso converter uma data de volta para timestamp?
Sim. O mesmo campo aceita os dois sentidos: escreva um número e obtém uma data; escreva uma data como 2024-05-20 ou 2024-05-20T09:33:20Z e obtém o valor epoch. Não há modo nenhum para trocar.
Lida com datas anteriores a 1970?
Sim. Os timestamps anteriores ao epoch são simplesmente negativos — -86400 é 31 de dezembro de 1969 — e os valores negativos são aceitos e convertidos normalmente.
Por que o meu timestamp mostra uma data diferente da esperada?
Quase sempre por um de dois motivos: a leitura segundos/milissegundos não é a que assumiu (veja a etiqueta e troque-a), ou está comparando um valor UTC com uma expectativa em hora local. A ferramenta mostra as duas linhas lado a lado para que veja qual dos casos é.
O que é o problema do ano 2038?
Os sistemas que armazenam segundos epoch num inteiro de 32 bits com sinal transbordam a 19 de janeiro de 2038 e passam a um número negativo, dando datas em 1901. Tudo o que usa valores de 64 bits — ou seja, quase tudo o que é moderno — não é afetado, mas os sistemas embebidos herdados e as colunas antigas de bancos de dados ainda podem estar em risco.
Por que o meu timestamp tem dezoito dígitos?
Porque provavelmente não é um timestamp Unix. Os segundos Unix têm hoje dez dígitos e os milissegundos treze; dezoito é a cara de um pulso de cem nanossegundos, que é o que o Windows FILETIME conta desde 1601 e o que o .NET conta desde o início do ano 1. Dezesseis dígitos são o outro caso comum: o mesmo instante em microssegundos. A seção sobre epochs acima dá a constante a subtrair em cada caso.
Como converto uma data em timestamp Unix no Python?
Construa um datetime ciente do fuso — um que carregue um tzinfo — chame o método timestamp dele e trunque o resultado para inteiro. O bloco de código acima tem a linha, e a mesma seção mostra o mesmo trabalho no shell e em JavaScript. Toda a dificuldade está no tzinfo: se você o omitir, o Python lê os seus números como hora local da máquina e devolve um valor diferente sem avisar.
O timestamp que introduzo é enviado para algum lugar?
Não. A análise, a conversão e a formatação rodam inteiramente no seu navegador, apoiando-se no suporte de datas e fusos horários da própria plataforma. Nada do que escrever sai do seu dispositivo.

Ferramentas relacionadas