Лучший способ извлечь часовой пояс из заголовка даты в Java? - PullRequest
6 голосов
/ 20 сентября 2008

Мне нужно сохранить часовой пояс, из которого было отправлено электронное письмо. Каков наилучший способ извлечь его из заголовка «Дата:» (дата RFC822)? И какой формат рекомендуется хранить в базе данных (я использую hibernate)?

Ответы [ 5 ]

1 голос
/ 20 сентября 2008

Вероятно, проще всего разобрать с JodaTime, так как он поддерживает ISO8601, см. Разбор и форматирование даты и времени в Java с Joda Time .

DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
System.out.println(parser2.parseDateTime(your_date_string));

Время всегда должно храниться в UTC (GMT) с часовым поясом, т. Е. После анализа преобразовать часовой пояс в GMT, удалить смещение летнего времени и сохранить исходный часовой пояс.

Вы должны сохранить дату с часовым поясом после преобразования в UTC.

Если вы удалите или не обработаете часовой пояс, это вызовет проблемы при работе с данными, поступившими из другого часового пояса.

0 голосов
/ 27 июля 2012

Я рекомендую использовать Mime4J .

Библиотека предназначена для разбора всех видов ерунды электронной почты. Для разбора дат вы должны использовать DateTimeParser .

int zone = new DateTimeParser(new StringReader("Fri, 27 Jul 2012 09:13:15 -0400")).zone();

После этого я обычно конвертирую datetime в DateTime Джоды . Не используйте SimpleDateFormatter, поскольку он не охватывает все случаи для RFC822.

Ниже вы получите Joda TimeZone (из зоны int выше), который превосходит Java TZ.

// Stupid hack in case the zone is not in [-+]zzzz format
final int hours;
final int minutes;
if (zone > 24 || zone < -24 ) {
    hours = zone / 100;
    minutes = minutes = Math.abs(zone % 100);
}
else {
    hours = zone;
    minutes = 0;
}
DateTimeZone.forOffsetHoursMinutes(hours, minutes);

Теперь единственная проблема заключается в том, что часовой пояс, который вы получите, всегда будет числовым часовым поясом, который все еще может быть неправильным часовым поясом пользователя, отправляющего электронное письмо (при условии, что почтовое приложение отправило пользователям TZ, а не только UTC) .

Например, -0400 не является EDT (т. Е. America / New_York), потому что не учитывает переход на летнее время.

0 голосов
/ 20 сентября 2008

Похоже, вы уже упоминали об этом в одном из ваших комментариев, но я думаю, что это ваш лучший ответ. Библиотека JavaMail содержит код синтаксического анализа заголовка даты RFC822 в javax.mail.internet.MailDateFormat. К сожалению, он не раскрывает синтаксический анализ TimeZone напрямую, поэтому вам нужно будет скопировать необходимый код прямо из javax.mail.internet.MailDateParser, но стоит воспользоваться уже сделанной тщательной работой.

Что касается хранения, то парсер выдаст вам дату в виде смещения, поэтому вы должны иметь возможность хранить ее точно как int (позволяя Hibernate преобразовать ее в вашу базу данных для вас).

0 голосов
/ 20 сентября 2008

Часовой пояс в электронном письме не показывает, в какой часовой пояс оно было отправлено. Некоторые программы используют когда-либо UTC или GMT. Конечно, часовой пояс является частью значения даты и времени и также должен быть разобран.

Почему ты хочешь это знать. - Вы хотите нормализовать метку времени? Затем используйте DateFormat для его анализа. - Вы хотите определить timezome пользователя, который отправил электронное письмо? Это не будет правильно работать.

0 голосов
/ 20 сентября 2008

Извлечение данных из заголовка с использованием некоторой подстроки или регулярного выражения. Разобрать дату с помощью SimpleDateFormatter, чтобы создать объект Date.

...