Lenient Java 8日期解析 [英] Lenient Java 8 Date parsing
问题描述
我想用 LocalDateTime
解析'2015-10-01'。我要做的是
I'd like to parse '2015-10-01' with LocalDateTime
. What I have to do is
LocalDate localDate = LocalDate.parse('2015-10-01');
LocalDateTime localDateTime = localDateTime.of(localDate, LocalTime.MIN);
但是我想在一遍中解析它,比如
But I'd like to parse it in one pass like
// throws DateTimeParseException
LocalDateTime date = LocalDateTime.parse('2015-10-01', DateTimeFormatter.ISO_LOCAL_DATE);
此外,字符串的一小部分也会引发异常。
Also a small difference of a string throws the exception as well.
// throws DateTimeParseException
LocalDate localDate = LocalDate.parse("2015-9-5", DateTimeFormatter.ISO_LOCAL_DATE);
我可以使用Java 8 Date API轻松解析日期字符串吗?
Can I parse date strings leniently with Java 8 Date APIs?
推荐答案
如果要将日期字符串解析为2015-10-01
和2015-9-5
到 LocalDateTime
对象,您可以构建自己的 DateTimeFormatter
using DateTimeFormatterBuilder
:
If you want to parse date String as "2015-10-01"
and "2015-9-5"
to LocalDateTime
objects, you can build your own DateTimeFormatter
using DateTimeFormatterBuilder
:
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(字段)
。引用Javadoc:
The variable length of each field is handled by the call to appendValue(field)
. Quoting the Javadoc:
像这样的可变宽度值的解析器通常表现得很贪婪,需要一个数字,但接受的数字是可能。
The parser for a variable width value such as this normally behaves greedily, requiring one digit, but accepting as many digits as possible.
这意味着它可以解析用1或2位数字格式化的月份和日期。
This means that it will be able to parse month and days formatted with 1 or 2 digits.
要构建 LocalDateTime
,我们还需要为此构建器提供 LocalTime
。这是通过使用 LocalTime 的每个字段,rel =noreferrer> parseDefaulting(字段,值)
。如果要解析的String中不存在该字段,则此方法将获取该字段的字段和默认值。因为在我们的情况下,时间信息不会出现在字符串中,所以将选择默认值,即该字段的有效值范围的最小值(通过调用 getMinimum
到 该字段的ValueRange
;也许我们也可以在这里硬编码0。)
To construct a LocalDateTime
, we also need to provide a LocalTime
to this builder. This is done by using parseDefaulting(field, value)
for each field of a LocalTime
. This method takes a field and a default value for that field if it is not present in the String to parse. Since, in our case, the time information will not be present in the String, the default values will be chosen, i.e. the minimum value for the range of valid values for that field (it is obtained by calling getMinimum
to the ValueRange
of that field; perhaps we could also hard-code 0 here).
如果要解析的String可能包含时间信息,我们可以使用 DateTimeFormatter
的可选部分,如下所示:
In the event that the String to parse might contain time information, we can use optional sections of DateTimeFormatter
, like this:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy")
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH)
.appendPattern("[ HH:mm]") // optional sections are surrounded by []
.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));
这篇关于Lenient Java 8日期解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!