如果你想将日期字符串(如"2015-10-01"
和"2015-9-5"
)解析为LocalDateTime
对象,可以使用DateTimeFormatterBuilder
创建自己的DateTimeFormatter
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy")
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH)
.parseDefaulting(HOUR_OF_DAY, HOUR_OF_DAY.range().getMinimum())
.parseDefaulting(MINUTE_OF_HOUR, MINUTE_OF_HOUR.range().getMinimum())
.parseDefaulting(SECOND_OF_MINUTE, SECOND_OF_MINUTE.range().getMinimum())
.parseDefaulting(NANO_OF_SECOND, NANO_OF_SECOND.range().getMinimum())
.toFormatter();
System.out.println(LocalDateTime.parse("2015-9-5", formatter));
System.out.println(LocalDateTime.parse("2015-10-01", formatter));
每个字段的变长是由调用
appendValue(field)
处理的。引用 Javadoc 的话:
对于这样一个可变宽度值的解析器,通常会贪婪地进行处理,需要一位数字,但接受尽可能多的数字。
这意味着它能够解析以 1 或 2 个数字格式化的月份和日期。
为了构造一个 LocalDateTime
,我们还需要向这个构建器提供一个 LocalTime
。这是通过使用每个 LocalTime
字段的 parseDefaulting(field, value)
来完成的。这个方法接收一个字段和一个默认值,如果字符串中没有该字段,则选择该字段的默认值。因为在我们的情况下,时间信息不会在字符串中出现,因此将选择默认值,即该字段有效值范围的最小值(它是通过调用 getMinimum
来获取该字段的 ValueRange
;也许我们在这里也可以硬编码为 0)。
如果要解析的字符串可能包含时间信息,我们可以使用 DateTimeFormatter
的可选节,如下所示:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy")
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH)
.appendPattern("[ HH:mm]")
.parseDefaulting(HOUR_OF_DAY, HOUR_OF_DAY.range().getMinimum())
.parseDefaulting(MINUTE_OF_HOUR, MINUTE_OF_HOUR.range().getMinimum())
.parseDefaulting(SECOND_OF_MINUTE, SECOND_OF_MINUTE.range().getMinimum())
.parseDefaulting(NANO_OF_SECOND, NANO_OF_SECOND.range().getMinimum())
.toFormatter();
System.out.println(LocalDateTime.parse("2015-9-5", formatter));
System.out.println(LocalDateTime.parse("2015-10-01", formatter));
System.out.println(LocalDateTime.parse("2015-1-1 10:10", formatter));