LocalDate 解析器无法将月份解析为字符串:’Aug’

huangapple go评论60阅读模式
英文:

LocalDate parser cannot parse month as a String: 'Aug'

问题

我试图使用LocalDate解析以下字符串:“04 Aug 2015”。

尝试了几种DateTimeFormatter的变化后,我在Stack Overflow上寻找答案,并发现一些答案中给出的解析示例对我不起作用。经过进一步调查,我发现在Java 14中无法解析包含字符串月份的日期,比如“Jul”、“Feb”... 但在Java 8和10中可以无缝工作。

抛出的异常是:

java.time.format.DateTimeParseException:无法在索引3处解析文本'04 Aug 2015'

在Java 14中是否对LocalDate/DateTimeFormatter进行了任何更改?我在文档中找不到相关信息。

以下是在Java 8/10上成功打印并在Java 14上引发DateTimeParseException的代码:

public static void main(String[] args) {
  DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMM yyyy");
  String anotherDate = "04 Aug 2015";
  LocalDate lds = LocalDate.parse(anotherDate, dtf);
  System.out.println(anotherDate + " , " + lds);
}

希望这有所帮助。

英文:

I am trying to parse the following string with LocalDate: "04 Aug 2015".

After trying a few variation of DateTimeFormatters, I looked for answers in SO and found out that some of the parsing examples given in answer did not work for me. After further investigation I have found out that java 14 fails to parse a date which include a string month such as "Jul", "Feb"... but in java 8 & 10 it worked flawlessly.

The Exception thrown was:

> java.time.format.DateTimeParseException: Text '04 Aug 2015' could not be parsed at index 3

Have there been any changes to LocalDate/DateTimeFormatter in java 14? I could not find anything in the documentation.

Here is the code that prints successfully on java 8/10 and throws a DateTimeParseException at java 14:

  public static void main(String[] args) {
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMM yyyy");
    String anotherDate = "04 Aug 2015";
    LocalDate lds = LocalDate.parse(anotherDate, dtf);
    System.out.println(anotherDate + " , " + lds);
  }

答案1

得分: 5

将“Aug”转化为“第8个月”并不是一项简单的工作;大多数语言中都没有“Aug”。

解析器作为工作的一部分输入区域设置,它除其他事项外还使用这个区域设置来翻译(缩写的)月份名称。

如果您不指定它,您会得到系统默认值,这可能会有问题(因为您在每个运行此代码的JVM上的默认值可能不同)。

我猜测您的JDK 14安装使用了与其他安装不同的默认区域设置。

按以下方式进行测试:

System.out.println(java.util.Locale.getDefault());

要修复您的解析代码,请使用以下代码:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.ENGLISH);

注意:虽然在Java代码中和无数的堆栈溢出示例中经常看到DTF.ofPattern("pattern");,但其中99%的代码行实际上是有bug的 - 鉴于Java通常部署在服务器上和/或此代码用于解析网络流量而不是本地键入的内容,使模式使用系统默认区域设置是不正确的。

就像您几乎永远不应该使用new FileWriter("filename")一样,而应该使用new FileWriter("filename", StandardCharsets.UTF_8),您几乎永远不应该使用DateTimeFormatter.ofPattern(pattern) - 如果您的IDE具有列出禁止使用方法的功能(必须附带一条注释解释您知道自己在做什么的方法),您应该将其添加进去。

英文:

Turning 'Aug' into 'the 8th month' is not an easy job; most languages don't have 'Aug'.

the parser takes in a locale as part of the job, and it uses this amongst other things to translate (shortened) month names.

If you don't specify it, you get the system default, which can be problematic (because it can be different on every JVM you run this on).

My guess is that your JDK14 install is using a different default locale than your other installs.

Test it as follows:

System.out.println(java.util.Locale.getDefault());

and to fix your parse code:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.ENGLISH);

NB: Whilst it is extremely common to see DTF.ofPattern("pattern"); in java code and in a million stack overflow examples, 99% of those lines of code are buggy - given that java is usually deployed on servers and/or this code is used to parse web traffic and not locally typed stuff, having the pattern use the system default locale is not correct.

Just like how you should almost never use, say, new FileWriter("filename"), instead using new FileWriter("filename", StandardCharsets.UTF_8);, you should almost never use DateTimeFormatter.ofPattern(pattern); - if your IDE has the ability to make a list of forbidden methods (methods for which a call MUST be accompanied by a comment explaining that you know what you're doing), you should add it.

huangapple
  • 本文由 发表于 2020年7月21日 21:02:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63015139.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定