我需要在 Java 中解析日期的 RFC 2822 字符串表示。示例字符串在这里:
2010 年 3 月 13 日星期六 11:29:05 -0800
它看起来很讨厌,所以我想确保我做的一切都是正确的,并且稍后会遇到奇怪的问题,因为通过 AM-PM/军事时间问题、UTC 时间问题、我没有预料到的问题等,日期被错误解释...
谢谢!
这是执行您所要求的快速代码(使用SimpleDateFormat)
String rfcDate = "Sat, 13 Mar 2010 11:29:05 -0800";
String pattern = "EEE, dd MMM yyyy HH:mm:ss Z";
SimpleDateFormat format = new SimpleDateFormat(pattern);
Date javaDate = format.parse(rfcDate);
//Done.
PS。我在这里没有处理异常和并发(因为解析日期时 SimpleDateFormat 不同步)。
如果您的应用程序使用英语以外的其他语言,您可能希望通过使用备用 SimpleDateFormat 构造函数来强制日期解析/格式化的语言环境:
String pattern = "EEE, dd MMM yyyy HH:mm:ss Z";
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
请记住 [day-of-week ","] 在 RFC-2822 中是可选的,因此建议的示例并未涵盖所有 RFC-2822 日期格式。此外,RFC-822 日期类型允许许多不同的时区表示法(obs-zone),“Z”格式说明符未涵盖这些表示法。
我想没有简单的出路,除了寻找“,”和“-|+”来确定使用哪种模式。
DateTimeFormatter.RFC_1123_DATE_TIME
由于 Java 8 实现了新的日期时间类:java.time.ZonedDateTime
和java.time.LocalDateTime
. ZonedDateTime
支持解析几乎开箱即用的 RFC 字符串:
String rfcDate = "Tue, 4 Dec 2018 17:37:31 +0100 (CET)";
if (rfcDate.matches(".*[ ]\\(\\w\\w\\w\\)$")) {
//Brackets with time zone are added sometimes, for example by JavaMail
//This must be removed before parsing
//from: "Tue, 4 Dec 2018 17:37:31 +0100 (CET)"
// to: "Tue, 4 Dec 2018 17:37:31 +0100"
rfcDate = rfcDate.substring(0, rfcDate.length() - 6);
}
//and now parsing...
DateTimeFormatter dateFormat = DateTimeFormatter.RFC_1123_DATE_TIME;
try {
ZonedDateTime zoned = ZonedDateTime.parse(rfcDate, dateFormat);
LocalDateTime local = zoned.toLocalDateTime();
} catch (DateTimeParseException e) { ... }
有一个执行 RFC-2822 日期解析的 javax.mail 类:
javax.mail.internet.MailDateFormat
包括可选和过时的格式。
做就是了 :
new javax.mail.internet.MailDateFormat().parse("Sat, 13 Mar 2010 11:29:00 -0800")
new javax.mail.internet.MailDateFormat().parse("13 Mar 2010 11:29:00 -0800")
new javax.mail.internet.MailDateFormat().parse("13 Mar 2010 11:29 -0800")
它将正确解析这些有效的 RFC-2822 日期
至于其他旧的 DateFormatter,MailDateFormat
该类不是线程安全的。