首页 > 解决方案 > 如何解决java.text.ParseException:无法解析的日期:“Sat Sep 14 2019 00:00:00 GMT+0530(印度标准时间)”?

问题描述

我需要转换Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)为日期。但我越来越

java.text.ParseException: Unparseable date: "Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)" exception

我试过了:

SimpleDateFormat formatter = new SimpleDateFormat("E MMM dd hh:mm:ss Z yyyy");

标签: java

解决方案


java.time

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            "EEE MMM dd uuuu HH:mm:ss 'GMT'xx (zzzz)", Locale.ENGLISH);
    String str = "Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)";
    TemporalAccessor parsed = formatter.parse(str);
    ZonedDateTime zdt = ZonedDateTime.from(parsed);
    // Check the offset against the time zone for validation
    ZoneOffset offset = ZoneOffset.from(parsed);
    if (offset.equals(zdt.getOffset())) {
        System.out.println(zdt);
    } else {
        System.err.println("Offset doesn’t match");
    }

此片段的输出是:

2019-09-14T00:00+05:30[亚洲/加尔各答]

不要使用SimpleDateFormatDate。Thise 类设计不佳且早已过时。相反,我使用的是现代 Java 日期和时间 API java.time。与它一起工作要好得多。

验证为王。如果有一天您收到一个偏移量(如+0530或)与时区(如或)-0400不一致的字符串,您将需要发现并采取适当的措施。因此,我从解析的日期时间中取出偏移量,并将其与 Java 从时区派生的偏移量进行比较。在这种情况下,他们确实同意了。如果不是因为需要这种验证,解析 a 的正常方法会更简洁:India Standard TimeAustralian Central Daylight TimeZonedDateTime

    ZonedDateTime zdt = ZonedDateTime.parse(str, formatter);

指定语言环境。 Sat,Sep并且India Standard Time是英文的。如果您不确定使用英语语言环境进行解析,则解析很可能会失败。如果不是今天,那么有一天当您在具有不同区域设置的计算机上运行程序时。

你的代码出了什么问题?

您的格式模式字符串中有几个错误。虽然您收到的错误消息SimpleDateFormat很笼统,但 java.time 有时更有帮助。让我们看看它是否可以帮助我们。使用您的格式模式字符串:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd hh:mm:ss Z yyyy", Locale.ENGLISH);
    ZonedDateTime zdt = ZonedDateTime.parse(str, formatter);

这让我们

java.time.format.DateTimeParseException:无法在索引 13 处解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”

索引 13 已经是东西了。字符串中的索引 13 是 in 所在的19位置2019。该parse方法使用您的格式模式来解析字符串并成功解析Sat Sep 14 20,因为它匹配E MMM dd hh. 它知道一个小时只能是 2 位数字,因此只解析20为 hour 和 then 对象,因为格式模式指定小时后有一个冒号,而 . 后面没有任何冒号20。您现在可能已经看到,我们应该在格式模式中指定一年(uuuuyyyy)之后。dd让我们修复,移动yyyy字符串:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss Z", Locale.ENGLISH);

java.time.format.DateTimeParseException:无法在索引 25 处解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”

我们大约是两倍。索引 25 是在哪里GMT+0530。所以这与格式模式 letter 不匹配Z。文档说这Z是针对区域偏移的,例如 +0000;-0800; -08:00。您的字符串GMT在偏移量之前。我们通过将其转义为用单引号括起来的文字来解决它:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss 'GMT'Z", Locale.ENGLISH);

java.time.format.DateTimeParseException:无法解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”,在索引 33 处找到未解析的文本

索引 33 是​​ 之后的空格GMT+0530。您的格式模式字符串到此结束。有一种方法可以指示解析器只解析尽可能多的字符串,但这会剥夺我们对时区的验证,所以我们不要诉诸于此。小写z用于时区名称:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss 'GMT'Z (zzzz)", Locale.ENGLISH);

java.time.format.DateTimeParseException:无法解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”:无法从 TemporalAccessor 获取 ZonedDateTime:{NanoOfSecond=0, MinuteOfHour=0, MilliOfSecond =0, MicroOfSecond=0, OffsetSeconds=19800, HourOfAmPm=0, SecondOfMinute=0},ISO,Asia/Kolkata 解析为 java.time.format.Parsed 类型的 2019-09-14

这是一个新的。需要注意的细节是HourOfAmPm=0。我们不打算在字符串中的 AM 或 PM 中添加一个小时,只是一天中的一个小时。错误是小时的小写hh。对于一天中从 00 到 23 的小时,我们需要大写HH

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ss 'GMT'Z (zzzz)", Locale.ENGLISH);

现在解析成功并给出与上面相同的结果。我想说的是 java.time 正在努力帮助我们获得正确的格式模式。

链接


推荐阅读