Разбор RFC 2822 в JAVA

Мне нужно разобрать строковое представление RFC 2822 даты на Java. Пример строки здесь:

Сб, 13 марта 2010 11:29:05 -0800

Это выглядит довольно неприятно, поэтому я хотел удостовериться, что все делаю правильно, и позже буду сталкиваться с такими странными проблемами, когда дата интерпретируется неправильно либо через AM-PM/Военные проблемы времени, проблемы времени UTC, проблемы, которые я не делаю предвидеть и т.д.

Спасибо!

Ответы

Ответ 1

Это быстрый код, который делает то, что вы спрашиваете (используя 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 не синхронизируется при разборе даты).

Ответ 2

Если ваше приложение использует другой язык, кроме английского, вам может потребоваться принудительно настроить локаль для синтаксического анализа даты/форматирования с помощью альтернативного конструктора SimpleDateFormat:

String pattern = "EEE, dd MMM yyyy HH:mm:ss Z";
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);

Ответ 3

Пожалуйста, имейте в виду, что [день недели], "] является необязательным в RFC-2822, поэтому предлагаемые примеры не охватывают все форматы даты RFC-2822. Дополнительно, тип даты RFC-822 допускал много разных обозначений часовых поясов (obs-zone), которые не покрываются спецификатором формата Z.

Я думаю, что нет простого выхода, кроме поиска "," и "- | +", чтобы определить, какой шаблон использовать.

Ответ 4

Начиная с Java 8 были реализованы новые классы datetime: 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) { ... }