Java8 の Date & Time API ではまった。

Java

日経ソフトウェア4月号の「至極の Java クイズ」で JSR310 の問題がでていた。

知らない内容が鍵となっていてとても勉強になった。

しかし、それにもかかわらずはまってしまった。

ここでクイズです。

下記プログラムを実行するとどうなるでしょうか?

1.2014-03-03

2.2014-3-03

3.2014-3-3

4.実行時エラー

解りましたでしょうか?

 

このプログラムは DateTimeFormatter でパターンを設定し、ResolverStyle を設定しただけのシンプルなものですね。

LocalDate d = LocalDate.parse(“2014/3/03”, DateTimeFormatter.ofPattern(“yyyy/M/d”)
                .withResolverStyle(ResolverStyle.STRICT));

この問題の答えは 4.実行時エラーです。

Exception in thread “main” java.time.format.DateTimeParseException: Text ‘2014/03/10’ could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2014, MonthOfYear=3, DayOfMonth=10},ISO of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1919)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1854)
    at java.time.LocalDate.parse(LocalDate.java:400)
    at jp.yucchi.localdateparsetest.LocalDateParseTest.main(LocalDateParseTest.java:15)
Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2014, MonthOfYear=3, DayOfMonth=10},ISO of type java.time.format.Parsed
    at java.time.LocalDate.from(LocalDate.java:368)
    at java.time.LocalDate$$Lambda$7/980546781.queryFrom(Unknown Source)
    at java.time.format.Parsed.query(Parsed.java:226)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1850)
    … 2 more

 

ResolverStyle.LENIENT もしくは ResolverStyle.SMART だと 2014-03-03 と表示されます。

何故、ResolverStyle.STRICT だとエラーになるか解りますか?

エラーメッセージを読んでピンッてきたかたもいると思います。

ResolverStyle.STRICT は厳密に判定を下すので DateTimeFormatter.ofPattern(“yyyy/M/d”) の y をきっちり解釈してしまうのです。

ここでパターン設定に使われている y は year-of-era となっています。

これがエラーを引き起こす原因です。

じゃあどうすればいいかというと u を使えばいいのです。

u は year なので厳密に判断される場合でも全然問題ないのです。

よって、このプログラムを正しく動作させるには

LocalDate d = LocalDate.parse(“2014/3/03”, DateTimeFormatter.ofPattern(“uuuu/M/d”)
                .withResolverStyle(ResolverStyle.STRICT));

と DateTimeFormatter.ofPattern(“yyyy/M/d”) を DateTimeFormatter.ofPattern(“uuuu/M/d”) としてあげればいいのです。

よく見かけるサンプルは DateTimeFormatter.ofPattern(“yyyy/M/d”) となっているのが多いので注意が必要ですね。(^_^)

Hatena タグ:

« »

Comment

Trackback

  1. buy amazing stuff ゆっちのBlog » Java8 の Date & Time API ではまった。

Leave a Reply

* が付いている項目は、必須項目です!

次の HTML タグと属性を利用できます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*

Trackback URL