从邮件中提取时区的最佳方式Java中的日期标题?

问题描述:

我需要存储发送电子邮件的时区。从电子邮件的'Date:'标题(RFC822日期)中提取它的最佳方法是?什么是建议格式存储在数据库中(我使用休眠)?从邮件中提取时区的最佳方式Java中的日期标题?

使用某种子串或正则表达式从头中提取数据。使用SimpleDateFormatter解析日期以创建Date对象。

+0

谢谢jhawk28。不过,我可以使用MailDateFormat类获取日期。该类还解析时区,但似乎没有简单的方法来查找TimeZone,除了从MailDateParser复制代码。 – mmartijn 2008-09-20 14:03:22

可能最容易与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后,您必须将时间存储在时区中。

如果您删除或不处理时区,则在处理来自不同时区的数据时会导致问题。

+0

**错误!**只要它是正确的,并且使用像乔达这样的现代日期时间库,它可以更好地将DateTime *与*时区一起存储。这是处理时区。通过丢弃时区并标准化为UTC,可以减少对用户有用的数据,尤其是在移动/全球应用程序的情况下。 **另外SimpleDateFormat不是线程安全的!** ...我被诱惑到-1你。 – 2012-07-27 14:49:21

+0

@AdamGent这就是我所说的“如果你删除或不处理它可能导致问题的时区...”。我会编辑以使这个晶莹剔透。 – 2012-07-27 21:14:27

+0

请删除博客文章too或atl注意制作simpledateformat公共静态数组的严重并发危险。 – 2012-07-28 14:34:37

电子邮件中的时区不会显示它发送的时区。某些程序使用UTC或GMT。当然,时区是日期时间值的一部分,也必须解析。

为什么你想知道它。 - 你想标准化时间戳吗?然后使用DateFormat解析它。 - 你想检测发送邮件的用户的时间表吗?这将无法正常工作。

看起来你已经在你的一个评论中提到了这个,但我认为这是你的最佳答案。 JavaMail库在javax.mail.internet.MailDateFormat中包含RFC822 Date标头解析代码。不幸的是,它不直接公开TimeZone解析,因此您需要直接从javax.mail.internet.MailDateParser复制必要的代码,但值得充分利用已经完成的仔细工作。

至于存储它,解析器会给你一个偏移量的日期,所以你应该可以把它存储得很好,就像一个int(让Hibernate将它翻译成你的数据库)。

我建议您使用Mime4J

该库是专为解析各种电子邮件垃圾。 对于解析日期,您可以使用其DateTimeParser

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

之后,我通常的日期时间转换为Joda's 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),因为它不考虑夏令时节省的费用。