Java 11 DateTimeParseException无法在索引20处解析

时间:2020-06-22 14:57:56

标签: java datetime

我试图在Java 11中将字符串转换为Date对象,下面的代码给了我例外。尝试了不同的方法,到目前为止没有运气。对解决此错误消息有帮助吗?

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)

3 个答案:

答案 0 :(得分:1)

一个好的IDE会对您尝试编译的代码产生警告。例如,Eclipse警告

类型为ofLocalizedDateTime(FormatStyle)的静态方法DateTimeFormatter应该以静态方式访问

Java允许您通过引用表达式访问类的static个成员。不过,您已经should not达成强烈共识,只是忽略语言功能。

对于您的具体情况,

new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
            .toFormatter()
            .ofLocalizedDateTime(FormatStyle.LONG)
            .withZone(odt.getOffset());

在类型为[...].toFormatter()的引用表达式DateTimeFormatter上调用静态DateTimeFormatter#ofLocalizedDate(FormatStyle)。您似乎认为它是在实际的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)。另外,提供给ZoneId的{​​{1}}解析为withZone时将被忽略。

答案 1 :(得分:0)

使用模式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

注释(Courtesy Basil Bourque:从ZonedDateTime转换为LocalDateTime几乎毫无道理。这种转换会丢弃宝贵的信息(时区),而不会增加任何价值。

答案 2 :(得分:0)

在我的例子中,我解析的日期字符串的 am/pm 是小写的,就像这样

<块引用>

2021 年 5 月 12 日下午 3:31

我必须先将 'pm' 转换为 'PM',然后使用格式化程序 DateTimeFormatter.ofPattern("MMMM d yyyy 'at' h:mm a");