Лучший способ извлечь часовой пояс из заголовка даты почты в Java?

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
0
2 781
5

Ответы 5

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

Спасибо jhawk28. Однако я могу получить дату с помощью класса MailDateFormat. Этот класс также анализирует часовой пояс, но, похоже, нет простого способа найти этот часовой пояс, кроме копирования кода из MailDateParser.

mmartijn 20.09.2008 18:03

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

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

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

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

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

Неправильный! Its far better to store the DateTime с the timezone so long as it is correct and your using a modern datetime library like Joda. That is handle the TimeZone. By throwing away timezone and normalizing to UTC your loosing data that could be valuable to the user particularly if its a mobile/global application. Также SimpleDateFormat не является потокобезопасным! ... I'm tempted to -1 you.
Adam Gent 27.07.2012 18:49

@AdamGent Это то, что я имел в виду, говоря «если вы удалите или не обработаете часовой пояс, это может вызвать проблемы ....». Я отредактирую, чтобы сделать это кристально ясным.

Richard Harrison 28.07.2012 01:14

Удалите также сообщение в блоге или обратите внимание на серьезную опасность параллелизма при создании общедоступного статического массива simpledateformat.

Adam Gent 28.07.2012 18:34

Я отказался от использования SimpleDateFormat для использования JodaTime, хотя рассмотрел тот, который встроен в JAXB

Richard Harrison 29.07.2012 13:23

Спасибо (извините за требовательность)! Также я понятия не имел, что JAXB имеет форматирование / синтаксический анализ времени. Какие классы JAXB это делают? Также ISO8601 несовместим с форматом RFC822. ISO - это превосходный формат, но, к сожалению, в электронных письмах используется формат RFC822.

Adam Gent 29.07.2012 18:02

@AdamGent javax.xml.bind.DatatypeConverter.parseDateTime (...). Также у меня нет проблем с вашими комментариями - они были полезны и улучшили качество ...

Richard Harrison 29.07.2012 18:07

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

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

Я хочу определить часовой пояс пользователя, отправившего электронное письмо. Почему это не сработает?

mmartijn 20.09.2008 18:24

Потому что некоторые программы отправляют время в формате UTC или GMT независимо от часового пояса пользователя. Это часовой пояс сформированной строки даты, а не пользовательского компьютера.

Horcrux7 21.09.2008 01:15

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

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

Он может использовать парсер Mime4J DateTime вместо дружественного (ироничного) MailDateParser с ограниченной областью видимости. Смотрите мой ответ.

Adam Gent 29.07.2012 18:07

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

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

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

После этого я обычно конвертирую время в Дата и время Джоды. Не используйте 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), потому что не учитывает летнее время.

Другие вопросы по теме