使用 DateUtils 解析日期的问题

Problems with parsing dates using DateUtils

我正在尝试为 Android 应用程序解析各种略有不同的日期字符串。

两个例子是:

Thu, 20 Aug 2020 13:30:16 +0000
Wed, 19 Aug 2020 15:28:47 GMT

以下是我尝试解析这些字符串的方式:

Date pubDate = org.apache.commons.lang3.time.DateUtils.parseDate(dateString, 
    "EEE, dd MMM yyyy HH:mm:ss Z", "EEE, dd MMM yyyy HH:mm:ss zzz");

据我所知,这应该可行,但我在这两个示例中都遇到了 java.text.ParseException: Unable to parse the date: Wed, 19 Aug 2020 15:28:47 GMT 异常。我在这里做错了什么?

您的时区有两种不同的格式: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

第一个看起来遵循以下格式:

EEE, dd MMM yyyy HH:mm:ss Z", "EEE, dd MMM yyyy HH:mm:ss Z

而第二个格式为:

EEE, dd MMM yyyy HH:mm:ss Z", "EEE, dd MMM yyyy HH:mm:ss z

我没有发现你的格式有任何问题。

演示:

import java.text.ParseException;
import java.util.Date;

public class Main {
    public static void main(String[] args) throws ParseException {
        String[] dateStrings = { "Wed, 19 Aug 2020 15:28:47 GMT", "Thu, 20 Aug 2020 13:30:16 +0000" };
        for (String dateString : dateStrings) {
            Date pubDate = org.apache.commons.lang3.time.DateUtils.parseDate(dateString, "EEE, dd MMM yyyy HH:mm:ss Z",
                    "EEE, dd MMM yyyy HH:mm:ss zzz");

            System.out.println(pubDate);
        }
    }
}

输出:

Wed Aug 19 16:28:47 BST 2020
Thu Aug 20 14:30:16 BST 2020

不过,我强烈建议你停止使用过时的和error-pronejava.utildate-timeAPI和SimpleDateFormat.切换到 modern java.time date-time API and the corresponding formatting API (java.time.format). Learn more about the modern date-time API from Trail: Date Time.

使用现代 date-time API:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test strings
        String[] dateStrings = { "Wed, 19 Aug 2020 15:28:47 GMT", "Thu, 20 Aug 2020 13:30:16 +0000" };

        // Define formatter
        DateTimeFormatter formatter = DateTimeFormatter
                .ofPattern("[EEE, dd MMM yyyy HH:mm:ss Z][EEE, dd MMM yyyy HH:mm:ss zzz]", Locale.ENGLISH);

        for (String dateString : dateStrings) {
            ZonedDateTime zdt = ZonedDateTime.parse(dateString, formatter);

            System.out.println(zdt);
        }
    }
}

输出:

2020-08-19T15:28:47Z[GMT]
2020-08-20T13:30:16Z

如果您的 android 版本不符合 Java-8,您可以使用 ThreeTen-BackportCheck. Check

向后移植

您的格式内置于 java.time

使用DateTimeFormatter.RFC_1123_DATE_TIME;它适用于你的两个字符串。它实际上是相同的格式,只是与 UTC(或 GMT)的偏移量表示不同。 DateTimeFormatter 是 java.time 的一部分,现代 Java 日期和时间 API。我建议您更喜欢 java.time 而不是 DateDateUtils,也是因为 Date class 设计不佳且早已过时。

    String s = "Thu, 20 Aug 2020 13:30:16 +0000";
    OffsetDateTime dt = OffsetDateTime.parse(s, DateTimeFormatter.RFC_1123_DATE_TIME);
    System.out.println(dt);

输出为:

2020-08-20T13:30:16Z

让我们尝试使用您的其他字符串示例:

    String s = "Wed, 19 Aug 2020 15:28:47 GMT";

2020-08-19T15:28:47Z

问题:java.time 不需要 Android API 26 级吗?

java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)现代 API 出现 built-in.
  • 在 non-Android Java 6 和 7 中获取 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在较旧的 Android 上使用脱糖或 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。在后一种情况下,请确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接