2016-11-11 7 views
4

(ほとんど)任意の長さの日付文字列を解析しようとしています。私はのSimpleDateFormatとしていたアプローチは、私は新しい日付のAPIと「より良い」をやりたい、この任意の長さの日付を解析するDateTimeFormatterの文字列

private Date parseWithSimpleDateFormat(String dateString) throws ParseException { 
    String pattern = "yyyyMMddHHmmss".substring(0, dateString.length()); 
    SimpleDateFormat format = new SimpleDateFormat(pattern); 
    return format.parse(dateString); 
} 

...のようなものでした。私は何を作ってみたことは、次の結果

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 

と、次の

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); 
} 

である私がここに間違って何をやっている、またはどのように私はこれをさらにトラブルシューティングを行うのでしょうか?

答えて

4

あなたは今年の4桁以上の解析を回避するために、この修正されたフォーマッタを使用することができますなど、月(MM)のような他の分野とは対照的に

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(); 

を、年フィールドシンボルyはありませんがありますy文字の数で示される4桁の制限。

+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ではありません)。 –

関連する問題