Разбор 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) { ... }