如何将 Gmail 日期格式转换为 java.util.Date?

How to convert Gmail date format to java.util.Date?

我尝试使用 tPOP 从 Gmail 帐户检索邮件,然后将上次检索邮件的日期保存在某处(因此下次我 运行 我不会两次检索相同的邮件).

我可以从 gmail 邮件中检索到的唯一日期是这种格式:

Fri, 13 Apr 2018 02:26:19 -0700 (PDT)

如何将其转换为 Java.util.Date 格式?

您可以使用 SimpleDateFormat 完成此任务:

String dt = "Fri, 13 Apr 2018 02:26:19 -0700 (PDT)";
Date date = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH).parse(dt);

阅读更多:

迄今为止的其他答案,尽管它们可能在大多数情况下都有效,但请不要考虑 RFC1123 format (see section 5.2.14, that replaces the original RFC-822 定义的细微差别。

根据此规范定义,星期几字段是可选的(SimpleDateForamt 不能处理可选字段),时区可以作为 +/- 偏移量提供(SimpleDateFormat 中的大写 Z),或作为名称(SimpleDateFormat 中的小写 z)。

您可以创建 SimpleDateFormats 的组合,并查看哪个匹配,但这很慢。您可以使用 JodaTime 并构建可选部分,因为它有一个 API,但这也需要时间。

或者,如果您有 Java8+,您可以免费获得 DateTimeFormatter.RFC_1123_DATE_TIME。这不是该标准的完整实现,但如果您自己编写代码,它可能与您所获得的最接近。也可能更安全。

另请参阅:

改用Message-ID:header

the next time I run the job I won't be retrieving the same mails twice

为避免下载相同的邮件,请使用 Message-ID: header 而不是 Date:。这就是它的目的,以唯一地标识每条消息。不需要解析任何东西。

参见fields described here

示例:

Message-ID: <f6a363400703050910y7d591d42raf015fcef16f95ea@mail.gmail.com>
Date: Mon, 5 Mar 2007 09:10:41 -0800
From: UserName <address@gmail.com>
To: OtherUserName <address@system.com>
Subject: Subject Line
MIME-Version: 1.0

使用此字符串作为您的唯一标识符:

f6a363400703050910y7d591d42raf015fcef16f95ea@mail.gmail.com

tl;博士

String input = "Fri, 13 Apr 2018 02:26:19 -0700 (PDT)" ;
…
java.util.Date.from(                                     // Convert from modern classes `OffsetDateTime` & `Instant` to troublesome legacy class `Date`. Do so only if absolutely necessary.
    OffsetDateTime.parse(
        input.substring( 0 , input.indexOf( " (" ) ) ,   // Drop the ambiguity-prone pseudo-zone ` (PDT)` from the end.
        DateTimeFormatter.RFC_1123_DATE_TIME             // Parse using a built-in formatter defined for RFC 1123 strings.
    )
    .toInstant()                                         // Extract UTC value (`Instant`) from `OffsetDateTime`.
)                                                        // Returns a legacy `java.util.Date` object.

DateTimeFormatter.RFC_1123_DATE_TIME

中所述,Java 为 RFC 1123 中定义的这种格式提供了格式化程序(另请参阅 RFC 822)。

除了像PDT这样的伪时区代码不能被明确解析,因为它们不是标准化的,也不是唯一的。所以把它去掉。

String original = "Fri, 13 Apr 2018 02:26:19 -0700 (PDT)";
// Delete non-standard pseudo-zone at end.
String input = original;
if ( input.endsWith( ")" ) ) {
    int index = input.indexOf( " (" );
    input = input.substring( 0 , index );
}
DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME;
OffsetDateTime odt = OffsetDateTime.parse( input , f );

转储到控制台。

System.out.println( original );
System.out.println( input );
System.out.println( odt );

Fri, 13 Apr 2018 02:26:19 -0700 (PDT)

Fri, 13 Apr 2018 02:26:19 -0700

2018-04-13T02:26:19-07:00

转换

How can I convert this into a Java.util.Date format?

不要。 java.util.Date 是一个设计糟糕、令人困惑和麻烦的。躲开它。

但如果你必须与尚未更新为java.timeclasses的旧代码进行互操作,你可以来回转换。调用添加到旧 classes 的新方法。

OffsetDateTime 中提取一个 Instant,因为 class 替换 java.util.Date 以表示 UTC 中的时刻。

Instant instant = odt.toInstant() ;
java.util.Date d = java.util.Date.from( instant ) ;

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes.

从哪里获得java.time classes?

  • Java SE 8, Java SE 9, Java SE 10,及以后
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
  • Android
    • Android java.time classes.
    • 捆绑实施的更高版本
    • 对于较早的 Android (<26),ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.