Comparação de datas em JavaScript: como não pisar na bola e acelerar o código
\n\nImagine: você está programando uma loja virtual e precisa verificar se o desconto de um produto expirou. Ou está fazendo um calendário de tarefas, onde precisa filtrar os eventos de hoje. Ou está coletando análises — "mostre todos os pedidos da última semana". Em todos esses casos, você precisa comparar duas datas. Parece simples, não é? Mas o JavaScript, como sempre, está pronto para surpreender.
\n\nA pergunta "Compare two dates with JavaScript" no Stack Overflow acumulou milhares de visualizações — e não é por acaso. Desenvolvedores, mesmo experientes, frequentemente tropeçam em peculiaridades não óbvias ao trabalhar com datas. Neste artigo, não vamos apenas mostrar como comparar duas datas, mas também analisar qual método é mais rápido e qual é mais seguro. Vamos nessa!
\n\nPor que a comparação simples de datas não funciona?
\n\nVamos começar com o erro clássico de iniciante. Suponha que temos duas datas:
\n\nlet date1 = new Date('2024-03-15');\nlet date2 = new Date('2024-03-20');\n\nconsole.log(date1 < date2); // true\nconsole.log(date1 > date2); // false\nconsole.log(date1 == date2); // false\n\n\nCom os operadores < e > tudo funciona perfeitamente. O JavaScript converte os objetos Date em números (milissegundos) e os compara. Mas o operador == (e o estrito ===) se comporta de forma diferente. Ele compara referências de objetos, não seus valores. Duas datas diferentes são dois objetos diferentes, portanto == sempre retornará false, mesmo que as datas coincidam até o milissegundo.
Esta é a primeira armadilha. Daí a lição: nunca use == ou === para comparar datas. Apenas <, >, <=, >= ou métodos especiais.
Método getTime(): o padrão ouro para comparação de datas
\n\nA maneira mais confiável e eficiente é usar o método getTime(). Ele retorna o número de milissegundos desde 1º de janeiro de 1970 (época Unix). E o JavaScript sabe comparar números muito bem:
let date1 = new Date('2024-03-15T10:00:00');\nlet date2 = new Date('2024-03-15T10:00:00');\nlet date3 = new Date('2024-03-20T10:00:00');\n\nconsole.log(date1.getTime() === date2.getTime()); // true\nconsole.log(date1.getTime() < date3.getTime()); // true\nconsole.log(date1.getTime() > date3.getTime()); // false\n\n\nPor que isso é eficiente? Porque getTime() é uma operação muito leve. Ela simplesmente retorna o valor numérico já armazenado dentro do objeto Date. Sem parsing, sem cálculos adicionais. Apenas um número.
Vamos medir o desempenho. Aqui está um pequeno teste no console do navegador:
\n\nlet date1 = new Date('2024-01-01');\nlet date2 = new Date('2024-12-31');\n\nconsole.time('getTime');\nfor (let i = 0; i < 1000000; i++) {\n date1.getTime() < date2.getTime();\n}\nconsole.timeEnd('getTime');\n// Resultado: ~5-10 ms em navegadores modernos\n\n\nUm milhão de comparações em 10 milissegundos — é um resultado excelente. Para comparação, métodos alternativos podem ser 2 a 3 vezes mais lentos.
\n\nComparação de datas com valueOf()
\n\nO método valueOf() faz a mesma coisa que getTime() — retorna a representação numérica da data. Mas há um detalhe: ao usar operadores de comparação (<, >, etc.), o JavaScript chama implicitamente valueOf() para objetos Date. Ou seja, este código:
let date1 = new Date('2024-03-15');\nlet date2 = new Date('2024-03-20');\nconsole.log(date1 < date2);\n\n\nNa verdade, funciona como:
\n\nconsole.log(date1.valueOf() < date2.valueOf());\n\n\nPortanto, para comparações simples com < e >, você pode usar diretamente os objetos Date. Mas para igualdade exata (===), isso não funciona, e aqui você precisa de getTime() ou va