Em Java (e Groovy) é muito comum validarmos uma data digitada usando a classe SimpleDateFormat escrevendo código muito parecido com o exposto a seguir:
String dataInvalida = "45/42/2017"; // mês 42???
SimpleDateFormat formatoData = new SimpleDateFormat("dd/MM/yyyy");
try {
Date dataParseada = formatoData.parse(dataInvalida);
// se parseou, data válida!
} catch (ParseException ex) {
// data inválida! Não parseou
}
Por mais estranho que possa parecer, a data acima será considerada válida por SimpleDateFormat. Isto se deve ao aspecto “lenient” de sua implementação: um atributo do tipo boolean cujo valor default é true.
Se está definido como verdadeiro, SimpleDateFormat irá executar eurísticas internas para descobrir qual a data a partir da loucura que você forneceu. No exemplo acima a data encontrada será 15/7/2020 (experimente com o código acima).
Como resolver então? Simples: chamando o método setLenient e passando para este o valor false, tal como no exemplo abaixo:
String dataInvalida = "45/42/2017"; // mês 42???
SimpleDateFormat formatoData = new SimpleDateFormat("dd/MM/yyyy");
formatoData.setLenient(false); // simples!
try {
Date dataParseada = formatoData.parse(dataInvalida);
// se parseou, data válida (de verdade)!
} catch (ParseException ex) {
// data inválida! Não parseou. Bobagem enviada.
}
Problema resolvido, e não, infelizmente você não descobriu um bug na classe SimpleDateFormat. 🙂