Pergunta

O que é a melhor maneira de analisar uma data que pode estar em um dos seguintes formatos

 "dd-MM-yyyy HH:mm"
 "dd/MM/yyyy HH:mm"
 "dd.MM.yyyy HH:mm"

sem criar 3 SimpleDateFormats e analisar contra cada um.

Graças

Foi útil?

Solução

É provavelmente mais fácil de "ajustar" a cadeia de origem para um formato canônico:

if (text.length() == 16)
{
    if ((text.charAt(2) == '/' && text.charAt(5) == '/') ||
        (text.charAt(2) == '.' && text.charAt(5) == '.'))
    {
        text = text.substring(0, 2) + "-" + text.substring(3, 5) 
           + "-" + text.substring(6);
    }
}

Em seguida, use o formato da string usando "-".

Note que isso é muito específica, apenas substituindo exatamente os caracteres que você está em interessado, para evitar efeitos colaterais indesejados.

Outras dicas

Você pode executar dois substituir operações em primeiro lugar, de modo que você reduzir todos os três formatos para um único?

Você pode usar Apache commons lang DateUtils.parseDate

import java.text.ParseException;
import org.apache.commons.lang.time.DateUtils;

public class Test {

public static void main(String[] args) throws ParseException {

    String[] values = new String[]{"31-12-2009 12:00", "31/12/2009 12:00", "31.12.2009 12:00"};
    String[] parsePatterns = new String[]{"dd-MM-yyyy HH:mm", "dd/MM/yyyy HH:mm", "dd.MM.yyyy HH:mm"};

    for (String value : values) {
        System.out.println(DateUtils.parseDate(value, parsePatterns));
    }
}
}

Bem, internamente ele cria SimpleDateFormats, mas o que está errado com isso?

Como cerca de um regex:

"\\d\\d[./-]\\d\\d[./-]\\d\\d\\d\\d \\d\\d:\\d\\d"

No código, isso significaria algo como isto:

Pattern pattern = 
Pattern.compile("(\\d\\d)([./-])(\\d\\d)([./-])(\\d\\d\\d\\d) (\\d\\d):(\\d\\d)");

Matcher matcher = 
pattern.matcher("31-07-1983 15:30");

if (matcher.find() && matcher.group(2).equals(matcher.group(4))) {
  int day = Integer.parseInt(matcher.group(1));
  int month = Integer.parseInt(matcher.group(3));
  int year = Integer.parseInt(matcher.group(5));
  int hour = Integer.parseInt(matcher.group(6));
  int minute = Integer.parseInt(matcher.group(7));
} 

Fazê-lo sozinho com uma expressão regular:

public class SpecialDateFormat
{
    private final static Pattern PATTERN = Pattern.compile("(\\d{2})[\\.\\/\\-](\\d{2})[\\.\\/\\-](\\d{4}) (\\d{2}):(\\d{2})");

    public static Date parse(String text) throws ParseException {
        Matcher m = PATTERN.matcher(text);
        if (m.matches()) {
            int dd = Integer.parseInt(m.group(1));
            int mm = Integer.parseInt(m.group(2));
            int yy = Integer.parseInt(m.group(3));
            int hh = Integer.parseInt(m.group(4));
            int mi = Integer.parseInt(m.group(5));

            // NOTE: Checking if values are in valid ranges omitted

            Calendar cal = Calendar.getInstance();
            cal.set(yy, mm - 1, dd, hh, mi, 0);

            return cal.getTime();
        }
        else {
            throw new ParseException("Unparseable date: " + text, 0);
        }
    }
}

Note, porém, que esta não permite a mistura de diferentes separadores, por exemplo, "17-09 / 2009 12:00" seria permitido.

ParseExact pode tomar uma variedade de formatos. Você ainda tem que especificar todos os formatos, mas é uma única operação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top