使用DateUtils解析日期时遇到的问题

huangapple go评论76阅读模式
英文:

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的异常。我在这里做错了什么?

英文:

I am trying to parse various slightly different date strings for an Android application.

Two examples are:

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

Here is how I tried parsing these Strings:

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");

As far as I can tell this should work, but I am getting java.text.ParseException: Unable to parse the date: Wed, 19 Aug 2020 15:28:47 GMT exceptions for both those examples. What am I doing wrong here?

答案1

得分: 3

你的格式已经内置到 java.time 中

使用 DateTimeFormatter.RFC_1123_DATE_TIME;它适用于你的两个字符串。实际上,这是相同的格式,只是与UTC(或GMT)的偏移以不同的方式表示。DateTimeFormatterjava.time 的一部分,这是现代的 Java 日期和时间 API。我建议你优先选择 java.time 而不是 DateDateUtils,因为 Date 类的设计很差且已过时。

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 已经内置。
  • 在非 Android 的 Java 6 和 7 中,可以使用 ThreeTen Backport,这是现代类的后移版本(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在较旧的 Android 上,可以使用 desugaring 或者 Android 版的 ThreeTen Backport,称为 ThreeTenABP。在后一种情况下,请确保从 org.threeten.bp 及其子包中导入日期和时间类。

链接

英文:

Your format is built into java.time

Use DateTimeFormatter.RFC_1123_DATE_TIME; it works for both of your strings. It’s really the same format, only with the offset from UTC (or GMT) denoted differently. DateTimeFormatter is part of java.time, the modern Java date and time API. I recommend that you prefer java.time over Date and DateUtils, also because the Date class is poorly designed and long outdated.

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

Output is:

> 2020-08-20T13:30:16Z

Let’s try with your other string example:

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

> 2020-08-19T15:28:47Z

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.

答案2

得分: 1

你的时区使用了两种不同的格式:
第一种看起来遵循以下格式:

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
英文:

Your time zones are in 2 different formats:
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

The first one looks like it follows the format:

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

While the second is of the format:

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

答案3

得分: 1

我对您的格式没有任何问题。

**示例:**

    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

然而,我强烈建议您**停止**使用过时且容易出错的 `java.util` 日期时间 API 和 `SimpleDateFormat`。请转换为[现代化的](https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html) `java.time` 日期时间 API 以及相应的格式化 API (`java.time.format`)。从**[教程: 日期时间](https://docs.oracle.com/javase/tutorial/datetime/index.html)**了解有关现代日期时间 API 的更多信息。

# 使用现代日期时间 API:

    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    public class Main {
    	public static void main(String[] args) {
    		// 测试字符串
    		String[] dateStrings = { "Wed, 19 Aug 2020 15:28:47 GMT", "Thu, 20 Aug 2020 13:30:16 +0000" };
    
    		// 定义格式化器
    		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](https://www.threeten.org/threetenbp/) 进行回溯。查看 [如何在 Android 项目中使用 ThreeTenABP](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project)
英文:

I do not see any problem with your formats.

Demo:

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);
		}
	}
}

Output:

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

However, I strongly suggest you stop using the outdated and error-prone java.util date-time API and SimpleDateFormat. Switch to the 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.

Using modern 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);
		}
	}
}

Output:

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

If your android version is not compliant with Java-8, you can backport using ThreeTen-BackportCheck. Check How to use ThreeTenABP in Android Project

huangapple
  • 本文由 发表于 2020年8月21日 05:44:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63513526.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定