java.time.format.DateTimeParseExceptionは、Java8からJava11への移行で解析できませんでした

Sep 02 2020

これはJava8で機能します

LocalDateTime ldt = LocalDateTime.parse("4/11/17 00:00 AM", DateTimeFormatter.ofPattern("d/M/yy hh:mm[ ][a]"));

しかし、Java11では

java.time.format.DateTimeParseException: Text '4/11/17 00:00 AM' could not be parsed, unparsed text found at index 14
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)

誰かが私がこれがなぜであるかを理解するのを手伝ってくれる?ドキュメントを確認しましたが、DateTimeFormatterクラスに明らかな変更はありません。

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html

回答

9 rzwitserloot Sep 02 2020 at 18:40

何も変わっていません。「デフォルトプラットフォーム」のコードスタイルエラーを犯しています。これは、壊れたメソッドを使用してコードを壊すアンチパターンですが、単体テストではバグを見つけることはほとんど不可能です。あなたのコードは、たくさんの現金と評判がライン上にある生産時に爆発することになります。「幸いなことに」、今日、JDKを切り替えて、ロケール構成がJDKのインストール間で何らかの形で異なることに気付いたときに、このバグを発見しました。

私と同じように、これらの悪いメソッドを嫌うようになることをお勧めします:)これらのメソッドは、いくつかのパラメーターが「この値のデフォルトとしてプラットフォームにあるものは何でも」であると想定するメソッドであり、3つの一般的な原因は次のとおりです。注文:

  • 文字セットエンコーディング
  • ロケール
  • タイムゾーン

ofPattern(String)そのような方法の1つです。これは「プラットフォームのデフォルトロケール」を前提としており、明らかに、JDK8インストールでは英語またはそれに類似したものであり、JDK11インストールではそうではありません。フィールドのAM値としての解析aはロケールに依存します。明らかに、AMは英語主義であり、オランダ語やフランス語では意味がありません。

この問題を解決するには、次の2つの方法があります。

  1. IDEにメソッドを「実際にはこれを呼び出さないでください」とマークする機能がある場合は、これらすべてのメソッドをリストに追加することを強く検討する必要があります。プラットフォームのデフォルトが必要な場合は、Charset.defaultCharset()代わりに次のようなものを明示的に使用して本当にそれが欲しいのは明らかです。

  2. , Locale.ENGLISHパターンの後にアフターを押してコードを修正すると、すべてが再び雨のように正しくなります。

例:

LocalDateTime ldt = LocalDateTime.parse("4/11/17 00:00 AM",
  DateTimeFormatter.ofPattern("d/M/yy hh:mm[ ][a]",
  Locale.forLanguageTag("NL")));

JDK11と同じようにJDK8でも失敗します。

LocalDateTime ldt = LocalDateTime.parse("4/11/17 00:00 AM",
  DateTimeFormatter.ofPattern("d/M/yy hh:mm[ ][a]",
  Locale.ENGLISH));

JDK8とJDK11でも動作します。

NB:などの英語以外のロケールの束.GERMANYと.ITALYし、.FRANCE実際に正しく何とか解析AMを行うが、上記のように、(オランダ)、オランダはどこそれが動作しない例です。