Skip to content

Methodology

Metodologia de data e hora

Onde a aritmética ingênua de datas falha — e como cada ferramenta /datetime/ a contorna.

By Published

A aritmética de data e hora é uma das categorias de código mais tentadas e com mais bugs em qualquer base de código grande. As quatro ferramentas em nosso cluster de data e hora cada uma trata um subproblema diferente; esta página explica a matemática por trás de cada uma.

Calculadora de idade — empréstimo com consciência do calendário

Idade em anos-meses-dias não é apenas “hoje menos o aniversário dividido por 365,25” — essa aproximação acumula um dia de erro a cada 4-7 anos. O algoritmo correto usa empréstimo de calendário:

  1. Calcular diferença de anos: agora.ano − nascimento.ano.
  2. Calcular diferença de meses. Se agora.mês < nascimento.mês, emprestar 12 meses do contador de anos.
  3. Calcular diferença de dias. Se agora.dia < nascimento.dia, emprestar dias do contador de meses usando o comprimento real do mês do calendário anterior.

A etapa 3 é onde o código ingênuo falha. “Comprimento do mês anterior” não é 30 ou 31 — depende de qual mês anterior é (fevereiro tem 28 ou 29, o restante tem 30 ou 31). Nossa calculadora de idade usa new Date(year, month, 0) (que retorna o último dia do mês anterior) para obter o número certo sempre, inclusive em anos bissextos.

Exemplo prático

Nascimento: 31/12/1990. Hoje: 14/05/2026. Diferença de anos: 36. Diferença de meses: −7 (maio menos dezembro). Emprestar um ano, diferença de meses vira 5. Diferença de dias: 14 − 31 = −17. Emprestar um mês; o mês anterior é abril, que tem 30 dias, então adicionar 30, dando diferença de dias de 13. Resultado: 35 anos, 4 meses, 13 dias.

Diferença de datas — três unidades, um denominador

A ferramenta de diferença de datas relata o intervalo entre duas datas em dias, semanas e horas simultaneamente:

dias = (b.getTime() − a.getTime()) / 86.400.000
semanas = dias / 7 · horas = dias × 24

A sutileza é o tratamento de fuso horário. Ambas as datas são normalizadas para meia-noite UTC antes da subtração, então as transições de horário de verão não introduzem dias fracionários. Uma diferença de datas abrangendo uma mudança de horário de verão ainda é um número inteiro de dias, como os usuários esperam.

Dias úteis — segunda a sexta entre duas datas

O contador de dias úteis usa o algoritmo mais simples possível: percorrer cada dia do calendário entre as duas datas e incrementar um contador quando o dia da semana for segunda-sexta.

O que não está incluído: feriados nacionais. A observância de feriados varia por país, por ano e por setor. A ferramenta de dias úteis permanece apenas com dias da semana intencionalmente.

Conversor de fuso horário — IANA tzdata + Intl.DateTimeFormat

Fusos horários são construções políticas, não geográficas, e suas regras mudam. Nossas ferramentas de conversão de fuso horário acessam esses dados através doIntl.DateTimeFormat integrado do navegador. Nunca empacotamos nosso próprio tzdata — isso importa porque o tzdata é atualizado várias vezes por ano conforme países mudam regras, e o tzdata no nível do sistema operacional é atualizado pelo fornecedor do SO em uma cadência de segurança mais rápida que a nossa.

O algoritmo de conversão de horário de parede

Dado “14:00 em 04/07/2026 em Europe/Istanbul, que horas são em America/Los_Angeles?”:

  1. Tratar “14:00 em 04/07/2026” como um timestamp UTC (chamá-lo de estimativa).
  2. Perguntar ao Intl.DateTimeFormat: na estimativa, qual deslocamento tem Europe/Istanbul? (UTC+3.)
  3. Ajustar: o instante UTC real é estimativa − 3 horas.
  4. Renderizar esse instante UTC no relógio de parede de Los_Angeles.

Isso trata zonas de meia hora (Índia, UTC+5:30) e zonas de 45 minutos (Nepal, UTC+5:45) sem casos especiais.

O padrão ISO 8601

Todas as entradas de data na interface usam o formato ISO 8601 (YYYY-MM-DD). Todos os objetos Date produzidos internamente são sem fuso horário na fronteira e só se tornam conscientes de fuso horário ao cruzar para o conversor de fuso horário. A saída do Intl.DateTimeFormat é consciente de localidade no idioma do navegador do usuário; os dados subjacentes são sempre ISO 8601 para armazenamento e serialização.

Frequently asked questions

Por que não usar uma biblioteca de datas como dayjs ou date-fns?
Usamos, internamente, nas partes que se beneficiam — mas cada função visível em /lib/datetime/ é escrita a partir de primitivas. Bibliotecas de datas trocam tamanho por conveniência, e nossa matemática é simples e estável o suficiente para que a dependência não valha a pena.
O conversor de fuso horário lida com datas históricas?
Dentro do alcance do IANA tzdata, sim. O IANA contém regras de transição de horário de verão retroativamente até aproximadamente 1970 para a maioria das zonas, e antes para um subconjunto. Para datas anteriores a 1970, o deslocamento retornado é o deslocamento moderno da zona, que pode ser historicamente impreciso. Não use o conversor de fuso horário para pesquisa genealógica.

Related

Published May 14, 2026