Java 11 无法在索引 20 处解析 DateTimeParseException
Java 11 DateTimeParseException could not be parsed at index 20
我正在尝试将字符串转换为 Java 中的 Date 对象 11. 下面的代码给出了异常。尝试了不同的方法,到目前为止没有运气。任何解决此错误消息的帮助?
String date = 'Mon Aug 02 16:33:10 EDT 2021'
OffsetDateTime odt = OffsetDateTime.now( ZoneId.systemDefault() ) ;
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy").toFormatter().ofLocalizedDateTime(FormatStyle.LONG) .withZone(odt.getOffset());
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
System.out.println(localDateTime);
System.out.println(formatter.format(localDateTime));
错误
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mon Aug 02 16:33:10 EDT 2021' could not be parsed at index 20
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
at java_time_LocalDateTime$parse.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
使用模式,EEE MMM dd HH:mm:ss z yyyy
。
此外,由于您有时区而不是日期时间字符串中的偏移量,因此您应该使用 ZonedDateTime
而不是 OffsetDateTime
。
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDate = "Mon Aug 02 16:33:10 EDT 2021";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy");
ZonedDateTime zdt = ZonedDateTime.parse(strDate, formatter);
System.out.println(zdt);
LocalDateTime ldt = zdt.toLocalDateTime();
System.out.println(ldt);
}
}
输出:
2021-08-02T16:33:10-04:00[America/New_York]
2021-08-02T16:33:10
注(): 从ZonedDateTime
转换成LocalDateTime
几乎肯定是没有意义的。这种转换会丢弃有价值的信息,即时区,而不会增加任何价值。
好的 IDE 会对您尝试编译的代码产生警告。例如,Eclipse 警告
The static method ofLocalizedDateTime(FormatStyle)
from the type DateTimeFormatter
should be accessed in a static way
Java 允许您通过引用表达式访问 class 的 static
成员。不过,大家一致认为您 should not 只是忽略了语言功能。
针对您的具体情况,
new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter()
.ofLocalizedDateTime(FormatStyle.LONG)
.withZone(odt.getOffset());
静态 DateTimeFormatter#ofLocalizedDate(FormatStyle)
是在 DateTimeFormatter
类型的引用表达式 [...].toFormatter()
上调用的。您似乎认为它是在实际的 DateTimeFormatter
实例上调用的,但实际上它只是一个 static
方法调用。 .toFormatter()
返回的实例被丢弃。您的代码本质上等同于
new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter(); // thrown away
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withZone(odt.getOffset());
换句话说,您的 formatter
具有 ofLocalizedDateTime
选择的格式,而不是您尝试使用的 "E MMM d H:m:s z yyyy"
。据推测,对于您的默认 Locale
,该格式无法解析您的日期字符串。
不清楚您是否打算使用该方法。如果您知道具有适当格式的相应语言环境,则可以跳过您的自定义模式并只使用选定的模式
Locale currentLocale = /* whatever is appropriate */;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(currentLocale);
然后解析你的日期字符串。
否则,完全忽略该方法,只使用您提供的模式和时区构建您的 DateTimeFormatter
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter()
.withZone(odt.getOffset());
您可以从 DateTimeFormatter
class javadoc 看出您的模式字符串
E MMM d H:m:s z yyyy
可以正确解析您的日期字符串
Mon Aug 02 16:33:10 EDT 2021
无关,你确定LocalDateTime
是你需要的吗?您实际上丢失了原始字符串中的时区信息 (EDT)。此外,提供给 withZone
的 ZoneId
将被忽略以解析为 LocalDateTime
.
在我的例子中,我解析的日期字符串有小写的 am/pm,像这样
May 12 2021 at 3:31 pm
我必须先将 'pm' 转换为 'PM',然后使用格式化程序 DateTimeFormatter.ofPattern("MMMM d yyyy 'at' h:mm a");
我正在尝试将字符串转换为 Java 中的 Date 对象 11. 下面的代码给出了异常。尝试了不同的方法,到目前为止没有运气。任何解决此错误消息的帮助?
String date = 'Mon Aug 02 16:33:10 EDT 2021'
OffsetDateTime odt = OffsetDateTime.now( ZoneId.systemDefault() ) ;
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy").toFormatter().ofLocalizedDateTime(FormatStyle.LONG) .withZone(odt.getOffset());
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
System.out.println(localDateTime);
System.out.println(formatter.format(localDateTime));
错误
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mon Aug 02 16:33:10 EDT 2021' could not be parsed at index 20
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
at java_time_LocalDateTime$parse.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
使用模式,EEE MMM dd HH:mm:ss z yyyy
。
此外,由于您有时区而不是日期时间字符串中的偏移量,因此您应该使用 ZonedDateTime
而不是 OffsetDateTime
。
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDate = "Mon Aug 02 16:33:10 EDT 2021";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy");
ZonedDateTime zdt = ZonedDateTime.parse(strDate, formatter);
System.out.println(zdt);
LocalDateTime ldt = zdt.toLocalDateTime();
System.out.println(ldt);
}
}
输出:
2021-08-02T16:33:10-04:00[America/New_York]
2021-08-02T16:33:10
注(ZonedDateTime
转换成LocalDateTime
几乎肯定是没有意义的。这种转换会丢弃有价值的信息,即时区,而不会增加任何价值。
好的 IDE 会对您尝试编译的代码产生警告。例如,Eclipse 警告
The static method
ofLocalizedDateTime(FormatStyle)
from the typeDateTimeFormatter
should be accessed in a static way
Java 允许您通过引用表达式访问 class 的 static
成员。不过,大家一致认为您 should not 只是忽略了语言功能。
针对您的具体情况,
new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter()
.ofLocalizedDateTime(FormatStyle.LONG)
.withZone(odt.getOffset());
静态 DateTimeFormatter#ofLocalizedDate(FormatStyle)
是在 DateTimeFormatter
类型的引用表达式 [...].toFormatter()
上调用的。您似乎认为它是在实际的 DateTimeFormatter
实例上调用的,但实际上它只是一个 static
方法调用。 .toFormatter()
返回的实例被丢弃。您的代码本质上等同于
new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter(); // thrown away
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withZone(odt.getOffset());
换句话说,您的 formatter
具有 ofLocalizedDateTime
选择的格式,而不是您尝试使用的 "E MMM d H:m:s z yyyy"
。据推测,对于您的默认 Locale
,该格式无法解析您的日期字符串。
不清楚您是否打算使用该方法。如果您知道具有适当格式的相应语言环境,则可以跳过您的自定义模式并只使用选定的模式
Locale currentLocale = /* whatever is appropriate */;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(currentLocale);
然后解析你的日期字符串。
否则,完全忽略该方法,只使用您提供的模式和时区构建您的 DateTimeFormatter
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter()
.withZone(odt.getOffset());
您可以从 DateTimeFormatter
class javadoc 看出您的模式字符串
E MMM d H:m:s z yyyy
可以正确解析您的日期字符串
Mon Aug 02 16:33:10 EDT 2021
无关,你确定LocalDateTime
是你需要的吗?您实际上丢失了原始字符串中的时区信息 (EDT)。此外,提供给 withZone
的 ZoneId
将被忽略以解析为 LocalDateTime
.
在我的例子中,我解析的日期字符串有小写的 am/pm,像这样
May 12 2021 at 3:31 pm
我必须先将 'pm' 转换为 'PM',然后使用格式化程序 DateTimeFormatter.ofPattern("MMMM d yyyy 'at' h:mm a");