Introdução: por que o Date() padrão não é suficiente?
O objeto Date embutido em JavaScript é uma ferramenta poderosa, mas nem sempre conveniente. Ao desenvolver aplicações complexas em Node.js (por exemplo, agendadores de tarefas, sistemas de análise ou serviços financeiros), os desenvolvedores enfrentam uma série de problemas:
- Mutabilidade: métodos como
setMonth()alteram o objeto original. - Suporte limitado a fusos horários:
Datefunciona apenas com hora local e UTC. - Dificuldade de formatação: não há equivalente nativo ao
strftime. - Parsing de strings:
new Date("2023-13-01")não lançará um erro, mas criará "2024-01-01".
Neste artigo, exploraremos abordagens avançadas para trabalhar com datas e horas em Node.js que ajudarão a evitar esses problemas e escrever um código mais confiável.
1. Intl.DateTimeFormat: formatação sem dependências externas
O JavaScript moderno (ES6+) fornece a API de internacionalização embutida Intl.DateTimeFormat. Esta é uma ferramenta poderosa que permite formatar datas e horas para qualquer localidade sem precisar de bibliotecas de terceiros.
Uso básico
const date = new Date('2024-03-15T14:30:00Z');
// Formatação para localidade russaconst formatterRU = new Intl.DateTimeFormat('ru-RU', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long', hour: '2-digit', minute: '2-digit'});
console.log(formatterRU.format(date));// "пятница, 15 марта 2024 г., 17:30"Opções avançadas: fusos horários e tempo relativo
// Formatação considerando o fuso horárioconst formatterTZ = new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'short'});console.log(formatterTZ.format(date));// "Friday, March 15, 2024 at 10:30 AM"
// Formatação relativa (Intl.RelativeTimeFormat)const rtf = new Intl.RelativeTimeFormat('pt', { numeric: 'auto' });console.log(rtf.format(-5, 'day')); // "há 5 dias"console.log(rtf.format(2, 'month')); // "em 2 meses"Esta abordagem é ideal quando se deseja evitar dependências desnecessárias, mas é necessária uma formatação flexível para a interface do usuário.
2. Biblioteca date-fns: modularidade e funcionalidade
date-fns é uma biblioteca moderna construída sobre princípios de programação funcional. Sua principal vantagem é a modularidade: você importa apenas as funções necessárias, o que reduz significativamente o tamanho do bundle.
Instalação e exemplos básicos
// Instalação: npm install date-fnsimport { format, addDays, subMonths, differenceInDays, isWeekend } from 'date-fns';import { ptBR } from 'date-fns/locale';
const today = new Date();
// Formatação com localidadeconsole.log(format(today, 'dd MMMM yyyy, EEEE', { locale: ptBR }));// "15 março 2024, sexta-feira"
// Aritmética de datasconst nextWeek = addDays(today, 7);const lastMonth = subMonths(today, 1);
// Diferença entre datasconst diff = differenceInDays(nextWeek, today);console.log(diff); // 7
// Verificação de fim de semanaconsole.log(isWeekend(today)); // true ou falseCenários complexos: comparação e validação
import { parse, isValid, isBefore, isAfter, startOfMonth, endOfMonth } from 'date-fns';
// Parsing seguroconst parsed = parse('2024-13-01', 'yyyy-MM-dd', new Date());console.log(isValid(parsed)); // false — data inválida
// Trabalho com intervalosconst start = startOfMonth(new Date(2024, 2, 1)); // 1 de marçoconst end = endOfMonth(new Date(2024, 2, 1)); // 31 de março
const targetDate = new Date(2024, 2, 15);if (isAfter(targetDate, start) && isBefore(targetDate, end)) { console.log('A data está em março de 2024');}date-fns