2016-11-11 66 views
4

我試圖解析(幾乎)任意長度的日期字符串。我使用SimpleDateFormat的方法是這樣的使用DateTimeFormatter解析任意長度的日期字符串

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

你可以使用這個修改的格式,以避免解析超過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字母數所示。

+0

謝謝,這應該解決我的問題。你碰巧有一個參考手頭?我忽略了這部分API文檔嗎? –

+0

@PatrickPeer如果您(非常)仔細比較了[API-doc]中解析常規數字和年份的部分(http://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter .html),那麼當給出4個或更多的符號時,你至少可以懷疑這種行爲有些奇怪。但是,這裏的javadoc真的不夠用。你也可以看看有更多細節的[CLDR-spec](http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns)。 JSR-310格式在很多方面都遵循CLDR(儘管不是1:1)。 –