解析日期的优雅解决方案

Elegant solution to parse date

我想将一些文本解析为日期。但是,不能保证文本具有所需的格式。它可能是 2012-12-122012 甚至 </code>.</p> <p>目前,我正在使用嵌套的 try-catch 块,但这不是一个好的方向(我想)。</p> <pre><code>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) {} } }

这个问题的优雅解决方案是什么?如果在评估期间发生异常,是否可以使用不存在的 Optionals ?如果是,如何?

这可以使用 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"

DateTimeFormatterBuilder class 包含实现此功能的构建块:

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,因为有足够的信息可用。

另请注意模式中使用“[...]”部分来定义可选内容。