解析日期的优雅解决方案

时间:2015-09-30 08:34:18

标签: java datetime java-8 java-time

我想将一些文本解析为日期。但是,无法保证文本具有所需的格式。它可能是2012-12-122012,甚至是

目前,我已经走上了嵌套try-catch块的道路,但这不是一个好的方向(我想)。

LocalDate parse;
try {
    parse = LocalDate.parse(record, DateTimeFormatter.ofPattern("uuuu/MM/dd"));
} catch (DateTimeParseException e) {
    try {
        Year year = Year.parse(record);
        parse = LocalDate.from(year.atDay(1));
    } catch (DateTimeParseException e2) {
        try {
              // and so on 
        } catch (DateTimeParseException e3) {}
    }
}

这个问题的优雅解决方案是什么?是否可以使用在评估过程中发生异常时不存在的Optional?如果是,怎么样?

2 个答案:

答案 0 :(得分:5)

这可以使用DateTimeFormatter可选部分以优雅的方式完成。可选部分由[令牌启动,并以]令牌结束。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyy[-MM-dd]]");
System.out.println(formatter.parse("2012-12-12")); // prints "{},ISO resolved to 2012-12-12"
System.out.println(formatter.parse("2012")); // prints "{Year=2012},ISO"
System.out.println(formatter.parse("")); // prints "{},ISO"

答案 1 :(得分:4)

DateTimeFormatterBuilder类包含使其工作的构建块:

LocalDate now = LocalDate.now();
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    .appendPattern("[uuuu[-MM[-dd]]]")
    .parseDefaulting(ChronoField.YEAR, now.getYear())
    .parseDefaulting(ChronoField.MONTH_OF_YEAR, now.getMonthValue())
    .parseDefaulting(ChronoField.DAY_OF_MONTH, now.getDayOfMonth())
    .toFormatter();
System.out.println(LocalDate.parse("2015-06-30", fmt));
System.out.println(LocalDate.parse("2015-06", fmt));
System.out.println(LocalDate.parse("2015", fmt));
System.out.println(LocalDate.parse("", fmt));

parseDefaulting()方法允许为特定字段设置默认值。在所有情况下,可以从结果中解析LocalDate,因为有足够的信息可用。

还要注意使用" [...]"模式中的部分用于定义可选的内容。