在某些情况下,Java 11 无法将字符串转换为 LocalDateTime



我有下面这些代码:

private void convertStringDatePosted() {
String stringDatePosted = "20 Janeiro 2021 00:26";
Locale locale = new Locale("pt", "MZ");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy HH:mm").withLocale(locale);
LocalDateTime aa = LocalDateTime.parse(stringDatePosted, formatter);
System.out.println(aa);
}

当我用java 8运行代码时,它工作了。但是在java 11中,它抛出了这个异常:java.time.format. datetimeparseexception: Text '20 Janeiro 2021 00:26' could not be parsed at index 3.

我也有类似的情况,在我想转换的字符串中有一个区域,代码是:

protected LocalDateTime getDatePosted() {
String dateScraped = "2021-08-15 09:00:28 (UTC+01:00)";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss (z)");
return LocalDateTime.parse(dateScraped, formatter);
}

如果在java 8中运行,它仍然可以工作,但在java 11中则不能。例外情况是:java.time.format.DateTimeParseException: Text '20 Janeiro 2021 00:26'无法在索引24处解析。

这个错误发生在macOS上,我还没有在其他操作系统上尝试过。

我不知道这个错误是由于java版本或其他东西。期待您的回复。非常感谢!

在里约热内卢大写还是小写J ?

在我看来有两个错误:一个在你的字符串中,它应该有一个小j在里约热内卢中,另一个在Java 8中,它接受了你的大写j。说我几十年前在葡萄牙时只学过几个葡萄牙语单词

不同语言的月份名称是地区数据的一部分。Java最多可以从四个来源获取语言环境数据。Java 8中的默认值是Java早期版本以来的内置区域设置数据。从Java 9开始,默认值是CLDR, Unicode公共区域数据存储库。因此,在Java 8中,Java自己的语言环境数据有大写j. CLDR,它也可以在Java 8中通过系统属性获得,有一个小j。一个有趣的观察是,当我指示Java 11使用Java自己的语言环境数据时,它也显示了小j。Java 8的错误已经修复。

有许多可能的解决方案。一种是指示格式化程序在解析时不关心大小写:

String stringDatePosted = "20 Janeiro 2021 00:26";
Locale locale = new Locale("pt", "MZ");
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("d MMMM yyyy HH:mm")
.toFormatter(locale);
LocalDateTime aa = LocalDateTime.parse(stringDatePosted, formatter);
System.out.println(aa);

输出是:

2021 - 01 - 20 - t00:26

解析UTC偏移量

我无法复制你的其他例子。你的getDatePosted方法在我的Oracle jdk-11.0.3上运行良好,并返回2021-08-15T09:00:28。我不知道为什么它不在你的电脑上。

您的代码还有另一个问题:您正在解析为LocalDateTime,因此丢掉了时区信息。不要那样做。例如,字符串2021-08-15 09:00:28 (UTC-12:00)2021-08-15 09:00:28 (UTC+14:00)在时间上表示非常不同的点,间隔26小时,但将被解析为相同的LocalDateTime。解析为ZonedDateTime以保留时区。如果您需要不同时区的时间(例如您自己的时区),请转换为该时区的ZonedDateTime。如果可以避免使用LocalDateTime,请不要使用它。

处理:如果不能将UTC+01:00解析为时区,可以使用以下方法:

protected OffsetDateTime getDatePosted() {
String dateScraped = "2021-08-15 09:00:28 (UTC+01:00)";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss ('UTC'xxx)", Locale.ROOT);
return OffsetDateTime.parse(dateScraped, formatter);
}

现在该方法返回2021-08-15T09:00:28+01:00。您还注意到UTC偏移量已被保留。

链接有关不同Java版本中语言环境数据的更多信息的相关问题:JDK dateformatter解析德语语言环境中的DayOfWeek, java8 vs java9

最新更新