JavaScript Date.now(): obter e converter timestamps Unix

Um guia focado em JavaScript Date.now(): obtenha o timestamp Unix atual, converta segundos vs milissegundos, transforme timestamps em objetos Date, formate com Intl e evite as armadilhas comuns de parsing.

Como o JavaScript armazena o tempo internamente

Todo Date do JavaScript é internamente um único float de 64 bits que representa milissegundos desde o epoch Unix (1 de janeiro de 1970 00:00:00 UTC). Esse número é o que Date.getTime() e Date.now() retornam. Não há fuso armazenado dentro de um Date — é sempre uma contagem de milissegundos UTC. A informação de fuso só importa ao formatar a data para exibição, e por isso o mesmo objeto Date pode aparecer como segunda à noite em Los Angeles e terça de manhã em Tóquio. Este artigo foca em Date.now() e em converter timestamps; para um percurso mais amplo de cada tarefa de timestamp no JavaScript, veja o guia de referência completo no link abaixo.

Obter o timestamp Unix atual

Use Date.now() para milissegundos e Math.floor(Date.now() / 1000) para segundos. Ambos têm amplo suporte e não exigem imports. O hábito de nomenclatura importante é incluir a unidade no nome da variável: createdAtMs, expiresAtSeconds ou unixSeconds. Nomes com unidade evitam que um futuro consumidor da API adivinhe o que significa um campo de timestamp sem unidade.

  • Date.now() → 1700000000000 (milliseconds, 13 digits)
  • Math.floor(Date.now() / 1000) → 1700000000 (seconds, 10 digits)
  • +new Date() → same as Date.now() via unary coercion
  • new Date().getTime() → same result, slightly more verbose

Date.now() vs performance.now()

Date.now() é para timestamps de relógio: logs, payloads de API, campos de banco, expiração de cache e qualquer coisa que precise se alinhar ao tempo de calendário real. performance.now() é para medir a duração decorrida dentro da página ou processo atual. É monotônico e de alta precisão, mas não é um timestamp Unix e não pode ser convertido em data real sem um ponto de referência adicional.

  • Use Date.now() quando o valor for armazenado, enviado a uma API ou exibido como data
  • Use performance.now() ao medir quanto tempo levaram a renderização, o parsing ou uma requisição
  • Não armazene performance.now() em um banco como hora de evento
  • Não subtraia dois valores de Date.now() para temporização sensível à segurança; mudanças no relógio do sistema podem afetá-los

Converter um timestamp em um Date

O construtor Date aceita milissegundos. Se o seu timestamp está em segundos (10 dígitos), multiplique por 1000 antes de passá-lo. Esquecer isso é o erro de timestamp mais comum no JavaScript. Uma verificação rápida é o número de dígitos: os segundos Unix atuais têm 10 dígitos, os milissegundos Unix atuais têm 13 dígitos, e uma chamada ao construtor Date deve receber a forma de 13 dígitos em milissegundos.

  • new Date(1700000000 * 1000) → Tue Nov 14 2023 22:13:20 UTC ✓ correct
  • new Date(1700000000) → Tue Jan 20 1970 16:13:20 UTC ✗ missing × 1000
  • new Date(1700000000 * 1000).toISOString() → '2023-11-14T22:13:20.000Z'
  • new Date(1700000000 * 1000).toUTCString() → 'Tue, 14 Nov 2023 22:13:20 GMT'

Formatação ciente de fuso com Intl

Use Intl.DateTimeFormat para uma saída ciente de localidade e fuso. Ele trata o horário de verão automaticamente e não exige bibliotecas externas. É o caminho integrado mais seguro para painéis, ferramentas de administração, páginas de status e timestamps voltados ao usuário, pois permite escolher explicitamente tanto a localidade quanto o fuso IANA.

  • new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'long' }).format(date)
  • date.toLocaleString('en-GB', { timeZone: 'Europe/London', hour12: false })
  • date.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
  • new Intl.DateTimeFormat('en-CA', { timeZone: tz }).formatToParts(date) → array of {type, value} for custom layouts

Parsear strings de data com segurança

O parsing é onde o JavaScript se torna surpreendente. Strings ISO com um Z ou offset explícito são seguras porque identificam um instante exato. Datas enxutas e strings informais são mais fáceis de ler, mas costumam depender das regras do navegador ou do fuso do runtime. Para contratos de API, prefira strings ISO 8601 com fuso ou timestamps Unix numéricos com a unidade escrita no nome do campo.

  • Safe: new Date('2026-05-19T14:30:00Z') — explicit UTC
  • Safe: new Date('2026-05-19T10:30:00-04:00') — explicit offset
  • Risky: new Date('05/19/2026') — locale-dependent and ambiguous
  • Risky: new Date('2026-05-19 10:30') — not a strict ISO timestamp in all runtimes

Erros comuns de timestamp no JavaScript

  • new Date(1700000000) em vez de new Date(1700000000 * 1000) — cai em 1970, não em 2023
  • getMonth() retorna 0–11, não 1–12 — use sempre date.getMonth() + 1 ao exibir
  • new Date('2024-01-01') é parseado como meia-noite UTC; new Date('2024/01/01') como meia-noite local
  • Somar 86400000 ms para «amanhã» quebra nas transições de horário de verão — use setDate(d.getDate() + 1)
  • Comparar objetos Date com === sempre falha — compare seus valores .getTime()

Checklist recomendado de timestamps no JavaScript

O padrão de produção mais simples é armazenar um único instante canônico e formatá-lo apenas na borda. Mantenha os timestamps em UTC, inclua as unidades nos nomes e converta para um fuso legível apenas na interface ou na camada de relatórios.

  • Use milissegundos Unix para estado apenas do navegador e construção de Date no JavaScript
  • Use segundos Unix ao chamar APIs que documentam o tempo Unix em segundos
  • Use ISO 8601 com Z ou um offset explícito quando humanos puderem inspecionar os payloads
  • Use Intl.DateTimeFormat com um timeZone explícito para exibir
  • Adicione testes em torno dos limites do horário de verão quando as datas de calendário locais importarem

FAQ sobre timestamps no JavaScript

Date.now() retorna segundos ou milissegundos?
Date.now() retorna milissegundos desde 1 de janeiro de 1970 00:00:00 UTC. Divida por 1000 e use Math.floor() quando uma API espera segundos Unix.
Por que new Date(1700000000) mostra 1970?
O construtor Date espera milissegundos. 1700000000 é um timestamp em segundos, então o JavaScript o lê como apenas 1,7 bilhão de milissegundos após o epoch. Use new Date(1700000000 * 1000).
Um Date do JavaScript armazena um fuso?
Não. Um Date armazena uma contagem de milissegundos UTC. O fuso é aplicado apenas ao formatar com métodos como toString(), toLocaleString() ou Intl.DateTimeFormat.
Como converto um timestamp Unix em um Date do JavaScript?
Passe milissegundos ao construtor: new Date(seconds * 1000) para um valor de 10 dígitos em segundos, ou new Date(ms) para um valor de 13 dígitos em milissegundos. Esquecer o × 1000 é por que um timestamp de 2023 pode aparecer como 1970.