Methodology
Metodologia de data e hora
Onde a aritmética ingênua de datas falha — e como cada ferramenta /datetime/ a contorna.
By Buğra SözeriPublished
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:
- Calcular diferença de anos:
agora.ano − nascimento.ano. - Calcular diferença de meses. Se
agora.mês < nascimento.mês, emprestar 12 meses do contador de anos. - 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.000semanas = 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?”:
- Tratar “14:00 em 04/07/2026” como um timestamp UTC (chamá-lo de
estimativa). - Perguntar ao Intl.DateTimeFormat: na
estimativa, qual deslocamento tem Europe/Istanbul? (UTC+3.) - Ajustar: o instante UTC real é
estimativa − 3 horas. - 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
- Calculadora de idade
- Diferença de datas
- Dias úteis
- Conversor de fuso horário
- Planejador de reuniões
- Conversor de timestamp Unix
- Guia de fusos horários para equipes remotas
- Diferença de datas para solicitações de visto
- Dias úteis para faturamento
- Dados: mudanças de horário de verão em 50 anos
- Glossário: UTC
- Glossário: ISO 8601
- Glossário: Timestamp Unix
- Glossário: Fuso horário IANA
Published May 14, 2026