I need to parse an RFC 2822 string representation of a date in Java. An example string is here:
Sat, 13 Mar 2010 11:29:05 -0800
It looks pretty nasty so I wanted to make sure I was doing everything right and would run into weird problems later with the date being interpreted wrong either through AM-PM/Military time problems, UTC time problems, problems I don't anticipate, etc...
Thanks!
This is quick code that does what you ask (using 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. I've not dealt with exceptions and concurrency here (as SimpleDateFormat is not synchronized when parsing date).
If your application is using another language than English, you may want to force the locale for the date parsing/formatting by using an alternate SimpleDateFormat constructor:
String pattern = "EEE, dd MMM yyyy HH:mm:ss Z";
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
Please keep in mind that the [day-of-week ","] is optional in RFC-2822, hence the suggested examples are not covering all RFC-2822 date formats. Additional, the RFC-822 date type allowed many different time zone notations(obs-zone), which are not covered by the "Z" format specifier.
I guess there is no easy way out, other than looking for "," and "-|+" to determine which pattern to use.
DateTimeFormatter.RFC_1123_DATE_TIME
Since Java 8 new datetime classes were implemented: java.time.ZonedDateTime
and java.time.LocalDateTime
. ZonedDateTime
supports the parsing of RFC strings nearly out of the box:
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) { ... }
There is a javax.mail class that perform the parsing of RFC-2822 dates :
javax.mail.internet.MailDateFormat
including the optional and obsolete formats.
Just do :
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")
It will correctly parse these valid RFC-2822 dates
As for other old DateFormatters, the MailDateFormat
class is not thread safe.
String dateTime = OffsetDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME); //RFC_1123 == RFC_2822
RFC 2822 date-time string contains timezone offset eg the given string Sat, 13 Mar 2010 11:29:05 -0800 has a timezone offset of -08:00 hours from UTC ie the equivalent date-time at UTC can be obtained by adding 8 hours to Sat, 13 Mar 2010 11:29:05 .
The modern date-time API API has OffsetDateTime
to represent a date-time with timezone offset.
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
class Main {
public static void main(String[] args) {
String strRFC2822DateTimeStr = "Sat, 13 Mar 2010 11:29:05 -0800";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("EEE, dd MMM uuuu HH:mm:ss XX", Locale.ENGLISH);
OffsetDateTime odt = OffsetDateTime.parse(strRFC2822DateTimeStr, parser);
System.out.println(odt);
// In case you need the equivalent date-time at UTC
OffsetDateTime odtUtc = odt.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odtUtc);
}
}
Output :
2010-03-13T11:29:05-08:00
2010-03-13T19:29:05Z
Learn more about the modern Date-Time API from Trail: Date Time .
Some useful links :
y
instead of u
but I prefer u
to y
.OffsetDateTime
with JDBC .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.