Introdução: Por que trabalhar com datas em TypeScript exige atenção especial
Trabalhar com datas e horas é uma das tarefas mais comuns e, ao mesmo tempo, traiçoeiras no desenvolvimento web. Em TypeScript, que é uma extensão fortemente tipada do JavaScript, o objeto Date herdou todas as "peculiaridades" de seu predecessor: meses não intuitivos (contagem a partir do zero), mutabilidade dos métodos e problemas com fusos horários. No entanto, usando tipagem forte e bibliotecas modernas, você pode escrever código seguro, previsível e legível para trabalhar com tempo.
Neste artigo, abordaremos tudo o que um desenvolvedor precisa saber: desde a criação básica de datas até o trabalho avançado com fusos horários e formatação. Você aprenderá como evitar erros comuns e quais ferramentas (nativas e de terceiros) são mais adequadas para projetos TypeScript.
1. Fundamentos: O objeto Date e sua tipagem em TypeScript
Criação e métodos básicos
Em TypeScript, assim como em JavaScript, o objeto nativo Date é usado para trabalhar com datas. O TypeScript fornece tipos prontos para ele, portanto, não são necessárias definições adicionais.
// Criando a data atualconst now: Date = new Date();console.log(now); // 2024-01-15T10:30:00.000Z
// Criando a partir de uma string (ISO 8601)const specificDate: Date = new Date('2024-12-31T23:59:59');
// Criando a partir de componentes (ano, mês [0-11], dia, horas...)const birthday: Date = new Date(1990, 0, 15); // 15 de janeiro de 1990// Atenção: mês 0 = Janeiro!Problema com mutabilidade
Os métodos do objeto Date alteram o objeto original. Isso pode levar a bugs inesperados. O TypeScript não pode evitar isso no nível de tipos, mas você pode usar abordagens imutáveis.
const date = new Date('2024-01-01');date.setDate(date.getDate() + 5); // mutação! date agora é 6 de janeiro// Melhor criar um novo objeto:const newDate = new Date(date.getTime() + 5 * 24 * 60 * 60 * 1000);Tipagem de Unix Timestamp
Frequentemente, as datas são passadas como números (milissegundos desde 1970). Use um type alias para clareza:
type UnixTimestamp = number;
function formatTimestamp(ts: UnixTimestamp): string { return new Date(ts).toISOString();}
const myTimestamp: UnixTimestamp = 1705315200000;console.log(formatTimestamp(myTimestamp));2. Formatação e parsing de datas
Métodos nativos de formatação
O JavaScript fornece métodos básicos para saída localizada. Em TypeScript, eles funcionam "prontos para uso":
const date = new Date('2024-06-15T14:30:00');
// Strings localizadasconsole.log(date.toLocaleDateString('pt-BR')); // "15/06/2024"console.log(date.toLocaleTimeString('en-US')); // "2:30:00 PM"console.log(date.toLocaleString('de-DE')); // "15.6.2024, 14:30:00"
// String ISO (conveniente para APIs)console.log(date.toISOString()); // "2024-06-15T11:30:00.000Z" (sempre UTC)Parsing de strings: perigos
O parsing de strings através do construtor new Date(str) pode produzir resultados inesperados em diferentes navegadores. É melhor usar Date.parse() com verificação explícita ou bibliotecas de terceiros.
// Método não confiávelconst parsed = new Date('2024/01/15'); // pode funcionar de forma instável
// Método confiável: ISO 8601const safeParse = (dateStr: string): Date | null => { const ts = Date.parse(dateStr); return isNaN(ts) ? null : new Date(ts);};
const result = safeParse('2024-01-15T10:00:00Z');if (result) { console.log(result.toISOString());}3. Manipulações avançadas e comparação
Comparação de datas
As datas podem ser comparadas diretamente com operadores de comparação, mas para comparação precisa (igualdade), é necessário converter para número:
const date1 = new Date('2024-01-01');const date2 = new Date('2024-01-0