4

我正在尝试以 EEE 的格式解析日期,dd MMM yyyy HH:mm:ss zzz,例如使用threeten的 DateTimeFormatter 等字符串“Tue, 16 May 2017 07:44:48 GMT”。但是,似乎由于某种原因无法解析时区名称(我试图在没有时区名称部分的情况下解析相同的字符串并且有效)。

下面是代码的解析部分:

DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime parsedDate = ZonedDateTime.parse(date, parseFormatter);

我收到以下错误:

org.threeten.bp.format.DateTimeParseException:无法在索引 26 处解析文本“2017 年 5 月 16 日星期二 13:02:16 GMT”

我为时区名称部分尝试了各种不同的格式(例如 z、zzz、Z、ZZZ),但没有任何效果。同样,如果我解析没有时区名称部分的子字符串日期(到 LocalDateTime),那么它可以工作,所以我确信问题出在时区名称上。有谁知道问题可能是什么?

4

2 回答 2

4

我不知道为什么你的代码不起作用。当我java.time在我的 Java 8 中使用这些类时它确实如此。所以这只是对可能修复的猜测:

    DateTimeFormatter parseFormatter = DateTimeFormatter.RFC_1123_DATE_TIME;
    ZonedDateTime parsedDate = ZonedDateTime.parse(date, parseFormatter);

您会注意到它在同一个齿上略有简化。

DateTimeFormatter.RFC_1123_DATE_TIME记录为

返回 RFC-1123 日期时间格式化程序,例如 'Tue, 3 Jun 2008 11:05:30 GMT'。

所以我认为它应该接受GMT作为时区名称。我应该说它适合你的日期字符串,它也适用于我的电脑。我相信无论语言环境如何,这个格式化程序都会使用英文缩写来表示星期几和月份(或者你可以尝试DateTimeFormatter.RFC_1123_DATE_TIME.withLocale(Locale.ENGLISH),但我真的认为没有必要)。

也就是说,他们说您应该避免使用三个和四个字母的时区缩写。有些是模棱两可的,有些不是完整的时区,这会导致进一步的模棱两可。+00:00虽然 GMT 不是最危险的,但如果您可以获取带有偏移量的日期字符串,例如或只是Z,而不是三个字母的区域名称,那么对于您的问题来说,一个坚如磐石的解决方案是。

请参阅问题和此答案中的两个示例,在 IdeOne.com 上实时运行。两者都成功。

于 2017-05-16T21:18:33.737 回答
1

tl;博士

在 macOS(不是 Android)上使用ThreeTen-Backport 1.3.4 项目库时:

  • 没有得到你的DateTimeParseException(解析成功)
  • 但是我确实得到了一个与Java 8 内置的 java.time 类中分配的时区不同的时区
    2017-05-16T13:02:16Z[Africa/Monrovia]。而不是2017-05-16T13:02:16Z[GMT]

Africa/Monrovia区?

我们中的一些人已经看到您的代码工作,显然使用 Java 8 中内置的 java.time 类。

但是您的问题专门针对 Java 6 和 Java 7 的这些类的后向端口。因此,我使用该ThreeTen-Backport项目库尝试了以下示例。

package com.example.threetenbp.example;

import org.threeten.bp.*;
import org.threeten.bp.format.*;

import java.util.Locale;

/**
 * By Basil Bourque.
 */
public class App {
    public static void main ( String[] args ) {
        App app = new App ( );
        app.doIt ( );
    }

    private void doIt ( ) {
        String input = "Tue, 16 May 2017 13:02:16 GMT";
        DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern ( "EEE, dd MMM yyyy HH:mm:ss z" , Locale.ENGLISH );
        ZonedDateTime parsedDate = ZonedDateTime.parse ( input , parseFormatter );

        System.out.println ("parsedDate.toString(): " + parsedDate );
    }

}

在 macOS Sierra 10.12.4 上使用 IntellJ 2017.1.x 为 Java 8 构建和运行时,我得到了一个奇怪的结果。我没有得到我的预期ZZ[GMT]最后的结果,而是得到了利比里亚的时区Africa/Monrovia。这是有效的,因为与 UTC 的偏移量确实为零(与 UTC/GMT 相同)。但这不是我们在 IdeOne.com上看到的 Java 8 类2017-05-16T13:02:16Z[GMT]

parsedDate.toString(): 2017-05-16T13:02:16Z[非洲/蒙罗维亚]

我没有 Java 6 或 Java 7 的实现可供我使用。但我确实尝试在 IntelliJ 中设置我的构建字节码设置以使用 Java 6。结果相同。

于 2017-05-17T02:57:01.470 回答