英文:
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)的偏移以不同的方式表示。DateTimeFormatter
是 java.time
的一部分,这是现代的 Java 日期和时间 API。我建议你优先选择 java.time
而不是 Date
和 DateUtils
,因为 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
及其子包中导入日期和时间类。
链接
- Oracle 教程:日期时间,解释了如何使用
java.time
。 - Java 规范请求 (JSR) 310,首次描述了
java.time
。 - ThreeTen Backport 项目,将
java.time
后移至 Java 6 和 7(ThreeTen 用于 JSR-310)。 - 通过 desugaring 可用的 Java 8+ API。
- ThreeTenABP,ThreeTen Backport 的 Android 版本。
- 问题:如何在 Android 项目中使用 ThreeTenABP,附有非常详细的解释。
英文:
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.
Links
- Oracle tutorial: Date Time explaining how to use java.time.
- Java Specification Request (JSR) 310, where
java.time
was first described. - ThreeTen Backport project, the backport of
java.time
to Java 6 and 7 (ThreeTen for JSR-310). - Java 8+ APIs available through desugaring
- ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论