Java 8에서 Java 11로 마이그레이션하는 동안 java.time.format.DateTimeParseException을 구문 분석 할 수 없습니다.

Sep 02 2020

이것은 Java 8에서 작동합니다.

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

하지만 Java 11에서는

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 설치간에 어떻게 든 다른 점을 알게되었습니다.

나는 당신이 나처럼 이러한 나쁜 방법에 대한 혐오감을 키울 것을 제안합니다. :)이 방법들은 어떤 매개 변수가 '당신의 플랫폼이이 값에 대한 기본값으로 무엇을 가지고 있든지'라고 가정하는 것들이며, 세 가지 일반적인 범인은 다음과 같습니다. 주문:

  • 문자셋 인코딩
  • 장소
  • 시간대

ofPattern(String)그러한 방법 중 하나입니다. 그것은 '플랫폼 기본 로케일'을 가정하고 분명히 JDK8 설치에서는 영어 또는 유사하지만 JDK11 설치에서는 그렇지 않습니다. 필드의 AM값으로 구문 분석 하는 a것은 로케일에 따라 다릅니다. 분명히 AM은 영어주의입니다. 네덜란드어 나 프랑스어로는 이해가되지 않습니다!

이 문제를 해결하려면 다음 두 가지를 수행해야합니다.

  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 : .GERMANYand .ITALY와 같은 비 영어 로케일은 .FRANCE실제로 어떻게 든 AM을 올바르게 구문 분석하지만 위에 표시된대로 네덜란드어 (네덜란드)가 작동하지 않는 예입니다.