我需要存储发送电子邮件的时区。从电子邮件的“日期:”标题(RFC822 日期)中提取它的最佳方法是什么?将它存储在数据库中的推荐格式是什么(我使用的是休眠)?
5 回答
使用 JodaTime 解析可能最容易,因为它支持 ISO8601,请参阅Date and Time Parsing and Formatting in Java with Joda Time。
DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
System.out.println(parser2.parseDateTime(your_date_string));
时间必须始终存储在带有时区的 UTC (GMT) 中 - 即在解析从时区转换为 GMT 并删除夏令时偏移并保存原始时区之后。
转换为 UTC 后,您必须将日期与时区一起存储。
如果您删除或不处理时区,则在处理来自不同时区的数据时会导致问题。
我建议您使用Mime4J。
该库旨在解析各种电子邮件垃圾。对于解析日期,您将使用它的DateTimeParser。
int zone = new DateTimeParser(new StringReader("Fri, 27 Jul 2012 09:13:15 -0400")).zone();
之后,我通常将日期时间转换为Joda 的 DateTime。不要使用 SimpleDateFormatter,因为它不会涵盖 RFC822 的所有情况。
下面将为您提供优于 Java 的 TZ的Joda TimeZone (来自上面的 int 区域)。
// 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),因为它没有考虑夏令时。
使用某种子字符串或正则表达式从标题中提取数据。使用 SimpleDateFormatter 解析日期以创建 Date 对象。
电子邮件中的时区不会显示它是在哪个时区发送的。有些程序使用 UTC 或 GMT。当然时区是日期时间值的一部分,也必须被解析。
你为什么想知道。- 你想规范化时间戳吗?然后使用 DateFormat 对其进行解析。- 你想检测发送电子邮件的用户的时区吗?这将无法正常工作。
看起来您已经在您的一条评论中提到了这一点,但我认为这是您最好的答案。JavaMail 库包含 RFC822 日期标头解析代码javax.mail.internet.MailDateFormat
。不幸的是,它没有直接公开 TimeZone 解析,因此您需要直接从 复制必要的代码javax.mail.internet.MailDateParser
,但值得利用已经完成的仔细工作。
至于存储它,解析器会将日期作为偏移量提供给您,因此您应该能够将其存储为一个int
(让 Hibernate 为您将其转换为您的数据库)。