Java 8에서 Java 11로 마이그레이션하는 동안 java.time.format.DateTimeParseException을 구문 분석 할 수 없습니다.
이것은 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
답변
아무것도 바뀌지 않았다. '기본 플랫폼'코드 스타일 오류를 커밋하고 있습니다. 이것은 깨진 메서드를 사용하고 코드를 깨는 안티 패턴이지만 단위 테스트로는 버그를 찾기가 거의 불가능합니다. 당신의 코드는 많은 현금과 명성이 라인에있을 때 프로덕션 시간에 폭파 될 것입니다. "다행히도", 오늘 JDK를 전환하여이 버그를 발견했으며, 로케일 구성이 JDK 설치간에 어떻게 든 다른 점을 알게되었습니다.
나는 당신이 나처럼 이러한 나쁜 방법에 대한 혐오감을 키울 것을 제안합니다. :)이 방법들은 어떤 매개 변수가 '당신의 플랫폼이이 값에 대한 기본값으로 무엇을 가지고 있든지'라고 가정하는 것들이며, 세 가지 일반적인 범인은 다음과 같습니다. 주문:
- 문자셋 인코딩
- 장소
- 시간대
ofPattern(String)그러한 방법 중 하나입니다. 그것은 '플랫폼 기본 로케일'을 가정하고 분명히 JDK8 설치에서는 영어 또는 유사하지만 JDK11 설치에서는 그렇지 않습니다. 필드의 AM값으로 구문 분석 하는 a것은 로케일에 따라 다릅니다. 분명히 AM은 영어주의입니다. 네덜란드어 나 프랑스어로는 이해가되지 않습니다!
이 문제를 해결하려면 다음 두 가지를 수행해야합니다.
IDE에 메서드를 '정말로 호출해서는 안 됨'으로 표시하는 기능이있는 경우 이러한 모든 메서드를 목록에 추가하는 것을 강력히 고려하고, 플랫폼 기본값을 원하는 경우
Charset.defaultCharset()대신 다음 과 같은 것을 명시 적으로 사용 하여 당신이 정말로 그것을 원한다는 것은 분명합니다., 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을 올바르게 구문 분석하지만 위에 표시된대로 네덜란드어 (네덜란드)가 작동하지 않는 예입니다.