使用DateTimeFormatter分析任意长度的日期字符串
我正在尝试解析(几乎)任意长度的日期字符串。我使用SimpleDataFormat的方法是这样的使用DateTimeFormatter分析任意长度的日期字符串,date,java-8,Date,Java 8,我正在尝试解析(几乎)任意长度的日期字符串。我使用SimpleDataFormat的方法是这样的 private Date parseWithSimpleDateFormat(String dateString) throws ParseException { String pattern = "yyyyMMddHHmmss".substring(0, dateString.length()); SimpleDateFormat format = new SimpleDateFo
private Date parseWithSimpleDateFormat(String dateString) throws ParseException {
String pattern = "yyyyMMddHHmmss".substring(0, dateString.length());
SimpleDateFormat format = new SimpleDateFormat(pattern);
return format.parse(dateString);
}
。。。我想用新的Date API做得更好。我得出的结论如下
private static final DateTimeFormatter FLEXIBLE_FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("yyyy[MM[dd[HH[mm[ss]]]]]")
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
private Date parseWithDateTimeFormatter(String dateString) {
LocalDateTime localDateTime = LocalDateTime.parse(dateString, FLEXIBLE_FORMATTER);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
Instant instant = zonedDateTime.toInstant();
return Date.from(instant);
}
结果如下:
parseWithDateTimeFormatter("2016"); // works as intended
parseWithDateTimeFormatter("201605"); // Text '201605' could not be parsed at index 0
parseWithDateTimeFormatter("20160504"); // Text '20160504' could not be parsed at index 0
parseWithDateTimeFormatter("2016050416"); // Text '2016050416' could not be parsed at index 0
parseWithDateTimeFormatter("201605041636"); // Text '201605041636' could not be parsed at index 0
我在这里做错了什么,或者我将如何进一步解决这个问题?您可以使用这个修改过的格式化程序,以避免解析一年中超过4位的数字:
private static final DateTimeFormatter FLEXIBLE_FORMATTER =
new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendPattern("[MM[dd[HH[mm[ss]]]]]")
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
与其他字段(如月份(MM)等)相比,年份字段符号y不限于y字母计数所指示的四位数字。谢谢,这应该可以解决我的问题。你手头有推荐人吗?这是我忽略的API文档的一部分吗?@PatrickPeer如果你(非常)仔细地比较分析一般数字和年份的部分,那么当给出4个或更多符号时,你至少可以怀疑行为有点奇怪。然而,javadoc在这里确实是不够的。你也可以看看哪个有更多的细节。JSR-310-CLDR在许多方面遵循了格式(尽管不是1:1)。