Formatação e Conversão de Tempo em JavaScript: Armadilhas Comuns
Aprenda a formatar e converter tempo em JavaScript sem surpresas: timestamps, strings ISO, fusos horários, DST, regras de parsing e padrões confiáveis.

O que geralmente dá errado com tempo em JavaScript
Bugs relacionados a tempo em JavaScript raramente parecem um “relógio errado”. Eles aparecem como pequenos deslocamentos confusos: uma data que está correta no seu laptop mas errada na máquina de um colega, uma resposta de API que parece ok até ser renderizada em outro fuso, ou um relatório que fica “um dia a menos” perto de uma mudança sazonal.
Os sintomas mais comuns
Normalmente você vai notar um (ou mais) destes:
- Uma hora a menos/mais: especialmente em torno do Horário de Verão, ou quando um valor é convertido inadvertidamente entre hora local e UTC.
- Um dia a menos/mais: um valor que representa só data (como “2025-12-23”) aparece como o dia anterior/próximo dependendo do fuso.
- Fuso horário errado: os horários parecem corretos, mas o offset (por exemplo,
+02:00) é diferente do esperado. - Formatação inconsistente: “funciona no Chrome” mas parece diferente no Safari, ou servidor e navegador discordam sobre como analisar uma string.
Por que isso acontece: “tempo” pode significar coisas diferentes
Uma grande fonte de dor é que a palavra tempo pode se referir a conceitos distintos:
- Um instante: um momento específico no mundo (ex.: “2025-12-23T10:00:00Z”). É o que normalmente você quer para logs, eventos e armazenamento em API.
- Uma data de calendário: um dia no calendário sem fuso horário (ex.: um aniversário, data de vencimento). Tratá-la como um instante pode deslocá-la para outro dia.
- Hora do relógio: “09:00 em Berlim”, que depende das regras de fuso e das mudanças de horário de verão.
O Date nativo do JavaScript tenta cobrir todos esses casos, mas representa primariamente um instante no tempo enquanto empurra você constantemente para a exibição local, o que facilita conversões acidentais.
No que este artigo se foca
Este guia é intencionalmente prático: como obter conversões previsíveis entre navegadores e servidores, como escolher formatos mais seguros (como ISO 8601) e como identificar armadilhas clássicas (segundos vs milissegundos, UTC vs local e diferenças de parsing). O objetivo não é mais teoria — é menos surpresas do tipo “por que mudou?”.
Tipos de dados de tempo: Timestamp, Date e String
Bugs de tempo em JavaScript frequentemente começam ao misturar representações que parecem intercambiáveis, mas não são.
As três representações que você verá mais
1) Epoch em milissegundos (number)
Um número simples como 1735689600000 normalmente significa “milissegundos desde 1970-01-01T00:00:00Z”. Representa um instante no tempo sem formatação ou fuso.
2) Objeto Date (invólucro de um instante)
Um Date armazena o mesmo tipo de instante que um timestamp. A parte confusa: quando você imprime um Date, o JavaScript o formata usando as regras locais do ambiente, a menos que você peça explicitamente o contrário.
3) String formatada (exibição humana)
Strings como "2025-01-01", "01/01/2025 10:00" ou "2025-01-01T00:00:00Z" não são todas a mesma coisa. Algumas são unambiguamente ISO (com Z), outras dependem da localidade, e algumas não incluem fuso horário.
“Instante no tempo” vs “hora para humano”
- Instante no tempo: “este momento exato globalmente” (melhor armazenado como epoch ms ou string ISO em UTC).
- Hora para humano: “o que o usuário deve ver” (depende de localidade e fuso).
O mesmo instante pode aparecer diferente conforme o fuso:
const instant = new Date("2025-01-01T00:00:00Z");
instant.toLocaleString("en-US", { timeZone: "UTC" });
// "1/1/2025, 12:00:00 AM"
instant.toLocaleString("en-US", { timeZone: "America/Los_Angeles" });
// "12/31/2024, 4:00:00 PM" (dia anterior)
Escolha uma “fonte de verdade”
Escolha uma representação interna e consistente (comum: epoch em milissegundos ou ISO 8601 em UTC) e mantenha-a em toda a app e APIs. Converta para/desde Date e strings formatadas apenas nas bordas: parsing de entrada e exibição na UI.
Timestamps: Segundos vs Milissegundos (fácil confundir)
“Timestamp” normalmente significa tempo Unix: a contagem desde 1970-01-01 00:00:00 UTC. O detalhe: sistemas diferentes usam unidades diferentes.
O Date do JavaScript é a origem de muita confusão porque usa milissegundos. Muitas APIs, bancos e logs usam segundos.
Regra prática
- Unix timestamp (segundos):
1704067200 - Timestamp JS (milissegundos):
1704067200000
Mesmo momento, mas a versão em milissegundos tem três dígitos a mais.
Conversões seguras (segundos ↔ milissegundos)
Use multiplicação/divisão explícita:
// seconds -> Date
const seconds = 1704067200;
const d1 = new Date(seconds * 1000);
// milliseconds -> Date
const ms = 1704067200000;
const d2 = new Date(ms);
// Date -> seconds
const secondsOut = Math.floor(d2.getTime() / 1000);
// Date -> milliseconds
const msOut = d2.getTime();
O bug clássico: passar segundos para Date()
Parece razoável, mas está errado quando ts está em segundos:
const ts = 1704067200; // seconds
const d = new Date(ts); // WRONG: treated as milliseconds
O resultado será uma data em 1970, porque 1.704.067.200 milissegundos é apenas cerca de 19 dias depois do epoch.
Heurísticas rápidas para debug
Quando não tiver certeza da unidade, adicione guardrails simples:
function asDateFromUnknownEpoch(x) {
// heurística: segundos ~1e9-1e10, milissegundos ~1e12-1e13
if (x < 1e11) return new Date(x * 1000); // assume seconds
return new Date(x); // assume milliseconds
}
const input = Number(valueFromApi);
console.log({ input, digits: String(Math.trunc(input)).length });
console.log('as ISO:', asDateFromUnknownEpoch(input).toISOString());
Se a contagem de “dígitos” for ~10, provavelmente são segundos. Se for ~13, provavelmente milissegundos. Imprima toISOString() ao depurar: é inequívoco e ajuda a detectar erros de unidade imediatamente.
Hora local vs UTC: por que sua saída se desloca
O Date do JavaScript pode confundir porque armazena um instante único, mas pode apresentar esse instante em fusos diferentes.
Internamente, um Date é essencialmente “milissegundos desde o epoch Unix (1970-01-01T00:00:00Z)”. Esse número representa um momento em UTC. O “deslocamento” ocorre quando você pede ao JavaScript para formatar esse momento como hora local (com base nas configurações da máquina) versus UTC.
Getters locais vs getters UTC
Muitas APIs de Date têm variantes local e UTC. Elas retornam números diferentes para o mesmo instante:
const d = new Date('2025-01-01T00:30:00Z');
d.getHours(); // hora em *fuso local*
d.getUTCHours(); // hora em UTC
d.toString(); // string em hora local
d.toISOString(); // UTC (sempre termina com Z)
Se sua máquina está em Nova York (UTC-5), aquele horário UTC pode aparecer como “19:30” do dia anterior localmente. Em um servidor configurado para UTC, aparecerá como “00:30”. Mesmo instante, exibição diferente.
Por que logs parecem “errados”
Logs frequentemente usam Date#toString() ou interpolam um Date implicitamente, que usa o fuso local do ambiente. Isso significa que o mesmo código pode imprimir timestamps diferentes no seu laptop, na CI e na produção.
Orientação prática
Armazene e transmita tempo em UTC (ex.: epoch ms ou ISO 8601 com Z). Converta para fuso do usuário apenas na exibição:
- Para APIs: prefira
toISOString()ou passe epoch ms - Para UI: formate no fuso do usuário usando
Intl.DateTimeFormat
Se você está construindo uma app rapidamente, vale a pena definir isso já nos contratos de API: nomeie campos claramente (createdAtMs, createdAtIso) e mantenha server (Go + PostgreSQL) e client (React) alinhados sobre o que cada campo representa.
Strings ISO 8601: o formato mais seguro para APIs
Se precisa enviar datas/horários entre browser, servidor e banco, strings ISO 8601 são a escolha padrão mais segura. São explícitas, amplamente suportadas e (o mais importante) carregam informação de fuso.
Use UTC explícito ou um offset explícito
Dois bons formatos para troca:
- Hora em UTC (recomendado quando o fuso local não importa):
2025-03-04T12:30:00Z - Hora local com offset (recomendado quando a hora do relógio local importa):
2025-03-04T12:30:00+02:00
O que significa o “Z”?
Z é Zulu, outro nome para UTC. Então 2025-03-04T12:30:00Z é “12:30 em UTC”.
Quando o offset importa?
Offsets são cruciais quando um evento está atrelado a um contexto local (compromissos, reservas, horário de funcionamento). 2025-03-04T12:30:00+02:00 descreve um momento que está duas horas à frente de UTC, e não é o mesmo instante que 2025-03-04T12:30:00Z.
Evite strings ambíguas
Strings como 03/04/2025 são uma armadilha: é 3 de março ou 4 de março? Usuários e ambientes interpretam de formas diferentes. Prefira 2025-03-04 (ISO date) ou um datetime ISO completo.
Round-trip seguro (string → Date → string)
const iso = "2025-03-04T12:30:00Z";
const d = new Date(iso);
const back = d.toISOString();
console.log(iso); // 2025-03-04T12:30:00Z
console.log(back); // 2025-03-04T12:30:00.000Z
Esse “round-trip” é exatamente o que você quer para APIs: consistente, previsível e consciente de fuso.
Armadilhas de parsing: Date.parse e diferenças entre navegadores
Date.parse() parece conveniente: dá uma string, recebe um timestamp. O problema é que, para qualquer coisa que não seja claramente ISO 8601, o parsing pode depender de heurísticas do navegador. Essas heurísticas já variaram entre motores e versões, então a mesma entrada pode ser parseada diferente (ou nem parseada) dependendo de onde o código roda.
Por que Date.parse() pode variar
JavaScript só padroniza parsing de forma confiável para strings no estilo ISO 8601 (e mesmo aí detalhes como fuso importam). Para formatos “amigáveis” — como "03/04/2025", "March 4, 2025" ou "2025-3-4" — os navegadores podem interpretar:
- Mês/dia vs dia/mês conforme pressupostos de localidade
- Falta de fuso como hora local em um engine, mas rejeitada em outro
- Strings ligeiramente malformadas como “próximas o bastante”… até que não sejam
Se você não consegue prever a forma exata da string, não consegue prever o resultado.
O caso surpreendente: YYYY-MM-DD
Uma armadilha comum é a forma "YYYY-MM-DD" (por exemplo, "2025-01-15"). Muitos desenvolvedores esperam que seja interpretada como meia-noite local. Na prática, alguns ambientes tratam essa forma como meia-noite em UTC.
Essa diferença importa: meia-noite em UTC convertida para hora local pode virar o dia anterior em fusos negativos (ex.: Américas) ou deslocar a hora inesperadamente. É uma maneira fácil de cair no bug “por que minha data está um dia fora?”.
Checklist de parsing: entrada de usuário vs entrada de servidor
Para entrada de servidor/API:
- Prefira ISO 8601 completo com fuso explícito, ex.:
2025-01-15T13:45:00Zou2025-01-15T13:45:00+02:00. - Trate valores que são só data como dados, não como um instante. Se for aniversário ou data de vencimento, mantenha como string (
"YYYY-MM-DD") e evite converter paraDatea menos que também defina o fuso pretendido.
Para entrada de usuário:
- Não aceite formatos ambíguos como
03/04/2025a menos que sua UI force o significado. - Prefira inputs controlados (date pickers) que produzam um formato conhecido.
- Se tiver que analisar texto livre, defina e aplique os formatos aceitos desde o início.
Use regras explícitas (não heurísticas)
Em vez de confiar em Date.parse() para “descobrir”, escolha um destes padrões:
- Aceite apenas ISO 8601 no servidor; rejeite o resto.
- Faça parsing manual de formatos conhecidos (divida a string e use
new Date(year, monthIndex, day)para datas locais). - Armazene e transmita timestamps (epoch ms) para instantes precisos e formate só na exibição.
Quando dados de tempo são críticos, “funciona na minha máquina” não é suficiente — torne suas regras de parsing explícitas e consistentes.
Formatação para humanos com Intl.DateTimeFormat
Se o objetivo é “mostrar uma data/hora do jeito que as pessoas esperam”, a melhor ferramenta em JavaScript é Intl.DateTimeFormat. Ela usa regras de localidade do usuário (ordem, separadores, nomes de meses) e evita a abordagem frágil de concatenar strings manualmente como month + '/' + day.
Por que é melhor que montar strings manualmente
Formatação manual muitas vezes hardcoda saída no estilo americano, esquece zeros à esquerda, ou produz resultados 24/12 horas conflitantes. Intl.DateTimeFormat também deixa explícito em qual fuso você está exibindo — crítico quando seus dados estão em UTC mas a UI deve mostrar a hora local do usuário.
Opções comuns que você vai usar
Para “formatar bonitinho”, dateStyle e timeStyle são as mais simples:
const d = new Date('2025-01-05T16:30:00Z');
// Local do usuário + fuso local do usuário
console.log(new Intl.DateTimeFormat(undefined, {
dateStyle: 'medium',
timeStyle: 'short'
}).format(d));
// Forçar um fuso específico (ótimo para horários de evento)
console.log(new Intl.DateTimeFormat('en-GB', {
dateStyle: 'full',
timeStyle: 'short',
timeZone: 'UTC'
}).format(d));
Se precisar de ciclo de hora consistente (por exemplo, opção de configurações), use hour12:
console.log(new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: true
}).format(d));
Um padrão prático para UI
Escolha uma função de formatação por “tipo” de timestamp na sua UI (horário de mensagem, log, início de evento) e mantenha a decisão de timeZone intencional:
- Use hora local para “quando aconteceu para mim”.
- Use um fuso fixo (frequentemente UTC) para logs de auditoria, eventos de servidor ou coordenação entre times.
Isso dá saída consistente e amigável sem precisar manter um conjunto frágil de strings de formatação customizadas.
Horário de Verão: o bug oculto de uma hora
O Horário de Verão (DST) é quando um fuso ajusta seu offset em relação ao UTC (tipicamente uma hora) em datas específicas. A parte traiçoeira: DST não apenas “muda o offset” — ele altera a existência de certos horários locais.
Horas locais inexistentes e duplicadas
Quando os relógios adiantam, uma faixa de horários locais não acontece. Por exemplo, em muitas regiões o relógio pula de 01:59 para 03:00, então 02:30 horário local é “inexistente”.
Quando os relógios atrasam, uma faixa de horários locais acontece duas vezes. Por exemplo, 01:30 pode ocorrer uma vez antes da mudança e outra depois, significando que o mesmo horário de relógio pode referir-se a dois instantes diferentes.
Somar 24 horas vs “mesmo horário local amanhã”
Esses não são equivalentes ao redor de fronteiras de DST:
- Somar 24 horas: “exatamente 24 * 60 * 60 segundos depois”
- Mesmo horário local amanhã: “amanhã às 9:00 no mesmo fuso local”
Se o DST começa hoje, “amanhã às 9:00” pode estar apenas 23 horas longe. Se o DST termina, pode estar 25 horas longe.
// Scenario: schedule “same local time tomorrow”
const d = new Date(2025, 2, 8, 9, 0); // Mar 8, 9:00 local
const plus24h = new Date(d.getTime() + 24 * 60 * 60 * 1000);
const nextDaySameLocal = new Date(d);
nextDaySameLocal.setDate(d.getDate() + 1);
// Around DST, plus24h and nextDaySameLocal can differ by 1 hour.
Por que setHours pode surpreender
Se você fizer date.setHours(2, 30, 0, 0) em um dia de “spring forward”, o JavaScript pode normalizar para um horário válido diferente (frequentemente 03:30), porque 02:30 não existe em hora local.
Abordagens mais seguras
- Faça aritmética em UTC para tempos decorrido (durations): use epoch ms e métodos UTC.
- Para agendamento local, seja explícito sobre a intenção: “amanhã às 9:00 local” deve usar operações de calendário (
setDate) em vez de somar milissegundos. - Ao trocar horários por API, prefira ISO 8601 com offset ou
Zpara que o instante seja inequívoco.
Durações vs Datas: não use Date para um temporizador
Uma fonte comum de bugs é usar Date para algo que não é um momento de calendário.
Um timestamp responde “quando isso aconteceu?” (um instante específico como 2025-12-23T10:00:00Z). Uma duração responde “por quanto tempo?” (como “3 minutos 12 segundos”). Conceitos diferentes — misturá-los gera matemática confusa e efeitos inesperados de fuso/DST.
Por que Date é a ferramenta errada para durações
Date sempre representa um ponto na linha do tempo relativo a um epoch. Se você armazenar “90 segundos” como um Date, na prática está guardando “1970-01-01 mais 90 segundos” em um fuso. Formatá-lo pode mostrar 01:01:30, deslocar uma hora ou adicionar uma data que você não quis.
Para durações, prefira números puros:
- Armazene durações em segundos ou milissegundos (escolha uma unidade e mantenha).
- Faça aritmética com números.
- Converta para string apenas na renderização.
Converter segundos para HH:mm:ss
Um formatador simples para timers ou durações de mídia:
function formatHMS(totalSeconds) {
const s = Math.max(0, Math.floor(totalSeconds));
const hh = String(Math.floor(s / 3600)).padStart(2, "0");
const mm = String(Math.floor((s % 3600) / 60)).padStart(2, "0");
const ss = String(s % 60).padStart(2, "0");
return `${hh}:${mm}:${ss}`;
}
formatHMS(75); // "00:01:15" (countdown timer)
formatHMS(5423); // "01:30:23" (media duration)
Se estiver convertendo a partir de minutos, multiplique primeiro (minutes * 60) e mantenha o valor numérico até a renderização.
Comparações, ordenação e intervalos sem surpresas
Ao comparar tempos em JavaScript, o mais seguro é comparar números, não texto formatado. Um objeto Date é essencialmente um invólucro sobre um timestamp numérico (epoch ms), então você quer que as comparações virem “número vs número”.
Comparações seguras (timestamps ganham)
Use getTime() (ou Date.valueOf(), que retorna o mesmo número) para comparar de forma confiável:
const a = new Date('2025-01-10T12:00:00Z');
const b = new Date('2025-01-10T12:00:01Z');
if (a.getTime() < b.getTime()) {
// a é anterior
}
// Também funciona:
if (+a < +b) {
// o + unário chama valueOf()
}
Evite comparar strings formatadas como "1/10/2025, 12:00 PM" — são dependentes de localidade e não ordenam corretamente. A exceção principal são strings ISO 8601 no mesmo formato e fuso (ex.: todas terminando com ...Z), que ordenam lexicograficamente.
Ordenação e filtragem por intervalo
Ordenar por tempo é simples se você ordenar por epoch ms:
items.sort((x, y) => new Date(x.createdAt).getTime() - new Date(y.createdAt).getTime());
Filtrar itens dentro de um intervalo é a mesma ideia:
const start = new Date('2025-01-01T00:00:00Z').getTime();
const end = new Date('2025-02-01T00:00:00Z').getTime();
const inRange = items.filter(i => {
const t = new Date(i.createdAt).getTime();
return t >= start && t < end;
});
“Início/fim do dia” (local vs UTC)
“Início do dia” depende se você quer hora local ou UTC:
// Início/fim do dia local
const d = new Date(2025, 0, 10); // 10 Jan em hora local
const localStart = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
const localEnd = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
// Início/fim do dia em UTC
const utcStart = new Date(Date.UTC(2025, 0, 10, 0, 0, 0, 0));
const utcEnd = new Date(Date.UTC(2025, 0, 10, 23, 59, 59, 999));
Escolha uma definição cedo e mantenha-a em todas as comparações e lógica de intervalo.
Checklist de debug: como diagnosticar um bug de conversão de tempo
Bugs de tempo parecem aleatórios até você identificar o que você tem (timestamp? string? Date?) e onde o deslocamento é introduzido (parsing, conversão de fuso, formatação).
1) Capture as “três visões” do mesmo momento
Comece registrando o mesmo valor de três maneiras diferentes. Isso revela rapidamente se o problema é segundos vs milissegundos, local vs UTC, ou parsing de string.
console.log('raw input:', input);
const d = new Date(input);
console.log('toISOString (UTC):', d.toISOString());
console.log('toString (local):', d.toString());
console.log('timezone offset (min):', d.getTimezoneOffset());
O que observar:
- Se
toISOString()estiver muito fora (ex.: ano 1970 ou futuro distante), suspeite de segundos vs milissegundos. - Se
toISOString()parece certo mastoString()está “deslocado”, você está vendo uma questão de exibição em fuso local. - Se
getTimezoneOffset()muda dependendo da data, você está cruzando horário de verão.
2) Verifique o ambiente: fuso e localidade
Muitos relatórios “funciona na minha máquina” são apenas padrões de ambiente diferentes.
- Browser: cheque configurações de fuso do SO e idioma do navegador. Depois registre:
console.log(Intl.DateTimeFormat().resolvedOptions());
- Node.js / servidor: confirme o fuso do processo:
console.log('TZ:', process.env.TZ);
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
Se seu servidor roda em UTC mas seu laptop roda em um fuso local, a saída formatada difere a menos que você especifique timeZone explicitamente.
3) Adicione testes onde tempo costuma quebrar
Crie testes unitários em torno das bordas de DST e horários extremos:
- Uma hora antes e depois da mudança de DST na zona relevante
- Fim de mês/ano, crossover de
23:30→00:30 - Múltiplos fusos se seu produto os suporta
Se você iterate rápido, considere incluir esses testes no scaffolding. Por exemplo, ao gerar uma app React + Go, adicione uma pequena suíte de “contrato de tempo” (exemplos de payload + asserts de parsing/formatação) para pegar regressões antes do deploy.
Checklist rápido antes de enviar
- Entradas têm contrato claro: epoch ms ou ISO 8601 com offset.
- Não há strings ambíguas como
"2025-03-02 10:00"sem fuso. - Formatação sempre especifica
localee (quando necessário)timeZone. - Testes cobrem fronteiras de DST para suas regiões alvo.
Padrões recomendados para manipular tempo de forma confiável
Manipulação confiável de tempo em JavaScript é, na maior parte, escolher uma “fonte de verdade” e ser consistente do armazenamento até a exibição.
Boas práticas simples
Armazene e calcule em UTC. Trate hora local do usuário como detalhe de apresentação.
Transmita datas entre sistemas como strings ISO 8601 com offset explícito (preferivelmente Z). Se mandar epochs numéricos, documente a unidade e mantenha consistente (milissegundos é o padrão comum em JS).
Formate para humanos com Intl.DateTimeFormat (ou toLocaleString), e passe timeZone quando precisar de saída determinística (por exemplo, sempre mostrar em UTC ou em uma região de negócios específica).
Guia de decisão: BD vs API vs UI
- Banco de dados: armazene um instante como UTC (epoch ms ou tipo datetime UTC). Evite datetimes “locais” a menos que seu domínio realmente precise de horas de relógio local (ex.: loja abre às 09:00).
- APIs: prefira ISO 8601 com
Z(ex.:2025-12-23T10:15:00Z). Se usar epochs, nomeie campos comocreatedAtMspara deixar a unidade óbvia. - UI: pegue o instante UTC armazenado e formate para a localidade do usuário. Em UIs de agendamento, rotule claramente o fuso e mantenha conversões explícitas.
Quando valer usar uma biblioteca
Considere uma biblioteca de data-hora dedicada se precisar de eventos recorrentes, regras complexas de fuso, aritmética segura em DST (“mesmo horário local amanhã”) ou muito parsing de entradas inconsistentes. O valor está em APIs mais claras e menos bugs de casos extremos.
Se quiser se aprofundar, veja mais guias sobre tempo em /blog. Se estiver avaliando ferramentas ou suporte, veja /pricing.
Perguntas frequentes
Que formato devo usar para marcas de tempo em JavaScript?
Use milissegundos desde a época ou uma string ISO 8601 em UTC como formato interno. Converta para um formato local apenas quando for mostrar o valor a uma pessoa.
Por que minha marca de tempo Unix vira uma data de 1970?
O Date do JavaScript espera milissegundos. Multiplique por 1000 uma marca de tempo Unix em segundos antes de passá-la para new Date().
Por que a mesma data mostra horários diferentes em computadores diferentes?
Um Date armazena um único instante, mas o JavaScript costuma exibi-lo no fuso horário local do computador. Compare toISOString() com toString() para saber se os dados mudaram ou se apenas a exibição mudou.
Como evitar que uma data mude em um dia?
Mantenha um valor que contenha apenas a data, como uma data de nascimento ou de fatura, no formato YYYY-MM-DD. Não o transforme em um Date a menos que também defina o fuso horário desejado.
Qual formato de data é mais seguro para uma API?
Envie um valor ISO 8601 completo com Z para UTC, como 2025-03-04T12:30:00Z, ou inclua um deslocamento explícito. Evite strings como 03/04/2025, porque pessoas e navegadores podem interpretá-las de formas diferentes.
Como devo formatar datas para os usuários?
Use Intl.DateTimeFormat e especifique um timeZone quando a tela precisar de um fuso fixo. Ele formata datas de acordo com a localidade do usuário sem criar strings manualmente.
Devo usar Date.parse para datas inseridas pelo usuário?
Não dependa dele para strings informais ou ambíguas. Aceite um formato ISO conhecido vindo de APIs ou analise entradas controladas do usuário com regras definidas por você.
Por que devo evitar usar Date para uma contagem regressiva ou duração?
Um Date marca um momento no calendário, enquanto uma duração é apenas uma quantidade de tempo. Armazene durações em segundos ou milissegundos e formate o número ao exibi-lo.
Como o horário de verão afeta datas em JavaScript?
Use milissegundos desde a época para cálculos de tempo decorrido. Para agendas como "amanhã às 9:00" em um fuso nomeado, use operações baseadas no calendário e teste as datas de transição do horário de verão.
Qual é a forma mais rápida de depurar um erro de horário em JavaScript?
Registre a entrada bruta, toISOString(), toString() e getTimezoneOffset(). Um valor ISO incorreto costuma indicar um problema de análise ou de unidade, enquanto uma string local diferente geralmente indica uma diferença na exibição do fuso horário.