ThreeTenABP:如何使用自定义日期格式/DateTimeFormatter 验证日期?

ThreeTenABP: How to validate date using a custom date format / DateTimeFormatter?

我正在使用 ThreeTenABP 并且似乎 运行 进入 LocalDate.parse(String) 和 LocalDate.parse(String, DateTimeFormatter) 之间的实施差异。

LocalDate.parse("31/02/1985", DateTimeFormatter.ofPattern("dd/MM/yyyy"))

解析为“1985-02-28”而不抛出异常。

LocalDate.parse("2015-02-31")

DateTimeParseException:无法解析文本“2015-02-31”:无效日期 'FEBRUARY 31'

documentation almost 暗示这一点 "The string must represent a valid date" 仅在无格式化程序方法中提及。

如何使用 threeten bp 验证自定义格式的日期,例如 31/02/1985?

主要区别可以解释为 ISO_LOCAL_DATE-formatter 默认是严格的。其他格式化程序默认为 smart。你引用的完整句子是这样的:

The string must represent a valid date and is parsed using DateTimeFormatter.ISO_LOCAL_DATE.

所以很明显,formatter-less 方法只能在严格模式下解析 ISO 兼容日期,而且只能解析一个 subset of ISO-8601,即:

uuuu-MM-dduuuuMMdd

关于严格模式,学习一下source code:

   public static final DateTimeFormatter ISO_LOCAL_DATE; 
   static { 
     ISO_LOCAL_DATE = new DateTimeFormatterBuilder() 
       .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD) 
       .appendLiteral('-') 
       .appendValue(MONTH_OF_YEAR, 2) 
       .appendLiteral('-') 
       .appendValue(DAY_OF_MONTH, 2) 
       .toFormatter(ResolverStyle.STRICT).withChronology(IsoChronology.INSTANCE); 
     } 

然而,严格模式似乎没有很好的文档记录。无论如何,如果你想用自定义格式化程序实现严格模式,那么只需调用它的方法 withResolverStyle(ResolverStyle.STRICT).