quarta-feira, 21 de setembro de 2011

Problemas no SimpleDateFormat

O uso da classe SimpleDateFormat é muito frequente para parsar datas que estão em formato String e transformá-las para Date. É uma classe muito útil, e que resolve só por si toda uma série de problema de conversão de datas.

Contudo, quando se cria uma instância desta classe para fazer a formatação, há um campo desta mesma classe que por defeito vem a true. Este campo é a propriedade Lenient. Esta propriedade, quando a true permite à instância aplicar uma série de heurísticas na formatação e assim tentar efectuar o parse. A aplicação destas heurísticas pode, de vez em quando, indicar resultados incorrectos como no exemplo mais abaixo.

Usando a máscara "yyyy/MM/dd" no SimpleDateFormat e efectuando um parse a uma String no formato "dd/MM/yyyy", o SimpleDateFormat irá indicar que a data é válida, quando era expectável que desse uma excepção. Além de formatar a data, o SimpleDateFormat devolverá uma data completamente diferente da original (objecto Date).

Exemplo INVÁLIDO



        SimpleDateFormat dateFormat = new SimpleDateFormat(
        "yyyy/MM/dd");
     
        try {
            dateFormat.parse("12/12/1233");
        } catch (ParseException ex) {
            System.out.println("12/12/1233 Invalida");
        }
     
        try {
            dateFormat.parse("1212/12/12");
        } catch (ParseException ex) {
            System.out.println("1212/12/12 Invalida");
        }

Ao contrário do que seria de esperar o resultado é:

Thu Apr 16 00:00:00 GMT 16
Wed Dec 12 00:00:00 GMT 1212

Em primeiro lugar deveria ter ocorrido uma mensagem a dizer:



12/12/1233 Invalida

pois "12/12/1233" não está no formato esperado ("yyyy/MM/dd").

Em segundo lugar:

A data Thu Apr 16 00:00:00 GMT 16 nada tem a ver com "12/12/1233".





Para corrigir o problema, é necessário indicar ao SimpleDateFormat para não aplicar heurísticas. Isso é feito usando o método setLenient(false). Fazendo isto o resultado já será o expectável.

Exemplo VÁLIDO

        SimpleDateFormat dateFormat = new SimpleDateFormat(
        "yyyy/MM/dd");
     
        dateFormat.setLenient(false);
     
        try {
           System.out.println(dateFormat.parse("12/12/1233"));
        } catch (ParseException ex) {
            System.out.println("12/12/1233 Invalida");
        }
     
        try {
            System.out.println(dateFormat.parse("1212/12/12"));
        } catch (ParseException ex) {
            System.out.println("1212/12/12 Invalida");
        }

O resultado é:

12/12/1233 Invalida
Wed Dec 12 00:00:00 GMT 1212

Como esperado.

Sem comentários: