java.time.format.DateTimeParseException n'a pas pu être analysé lors de la migration de Java 8 vers Java 11
Cela fonctionne dans Java 8
LocalDateTime ldt = LocalDateTime.parse("4/11/17 00:00 AM", DateTimeFormatter.ofPattern("d/M/yy hh:mm[ ][a]"));
Mais en Java 11, je reçois
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)
Quelqu'un peut-il m'aider à comprendre pourquoi? J'ai vérifié les documents et je ne vois aucun changement évident dans la classe 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
Réponses
Rien n'a changé. Vous commettez une erreur de style de code «plateforme par défaut». C'est un anti-pattern où vous utilisez une méthode cassée et cassez votre code, mais le bogue est presque impossible à trouver avec les tests unitaires; votre code finira par exploser au moment de la production lorsque beaucoup d'argent et de réputation sont en jeu. «Heureusement», vous avez trouvé ce bogue aujourd'hui en changeant de JDK et en ayant de la chance que les configurations locales soient quelque peu différentes entre vos installations JDK.
Je suggère que vous développiez autant d'aversion pour ces mauvaises méthodes que moi :) Ces méthodes sont celles qui supposent qu'un paramètre est `` tout ce que votre plate-forme a par défaut pour cette valeur '', et les 3 coupables courants sont, en ordre:
- Encodage du jeu de caractères
- Lieu
- Fuseau horaire
ofPattern(String)est une de ces méthodes; cela suppose «la langue par défaut de la plate-forme», et évidemment, sur votre installation JDK8, c'est l'anglais ou quelque chose de similaire et sur votre installation JDK11 ce n'est pas le cas. L'analyse en AMtant que valeur d'un achamp dépend des paramètres régionaux; évidemment, AM est un anglais, cela n'aurait aucun sens en néerlandais ou en français!
Il y a 2 choses à faire pour résoudre ce problème:
Si votre IDE a des fonctionnalités pour marquer une méthode comme `` vous ne devriez vraiment jamais appeler ça '', vous devriez fortement envisager d'ajouter toutes ces méthodes à la liste, et si vous voulez ensuite que la plate-forme par défaut, vous utilisez explicitement des choses comme à la
Charset.defaultCharset()place, pour faire clair, vous voulez vraiment ça.Corrigez votre code en poussant un
, Locale.ENGLISHaprès votre modèle et tout ira à nouveau comme la pluie.
Un exemple:
LocalDateTime ldt = LocalDateTime.parse("4/11/17 00:00 AM",
DateTimeFormatter.ofPattern("d/M/yy hh:mm[ ][a]",
Locale.forLanguageTag("NL")));
échouera sur JDK8 autant que sur JDK11.
LocalDateTime ldt = LocalDateTime.parse("4/11/17 00:00 AM",
DateTimeFormatter.ofPattern("d/M/yy hh:mm[ ][a]",
Locale.ENGLISH));
fonctionne également sur JDK8 et JDK11.
NB: Un tas de paramètres régionaux non anglais tels que .GERMANYet .ITALYet .FRANCEanalysent en fait correctement AM, mais comme indiqué ci-dessus, le néerlandais (Pays-Bas) est un exemple où cela ne fonctionnera pas.