Java 使用 GMT 字符串从字符串中解析日期

Java parse date from string with GMT string

我有以下日期字符串 Tue Feb 04 2020 16:11:25 GMT+0200 (IST),我正在尝试使用以下代码将其转换为日期时间:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM d yyyy HH:mm:ss O (zzz)", Locale.ENGLISH);
LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);

我遇到了以下异常:

Text Tue Feb 04 2020 16:11:25 GMT+0200 (IST) could not be parsed at index 28

我查看了以下 SO 问题 Java string to date conversion,我看到了

O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;

那为什么我得到了异常?

你写了一个 d 并且你通过了 04 你应该像下面这样写 dd 而不是 d

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss O (zzz)", Locale.ENGLISH);

LocalDate dateTime = LocalDate.parse("2020 年 2 月 4 日星期二 16:11:25 GMT+0200 (IST)", formatter);

原因之一是您试图将日期时间 String(日期、时间、时区和偏移量)解析为仅存储年、月和日的对象 (LocalDate) ,仅此而已。

使用合适的class,比如ZonedDateTime并稍微调整解析模式:

  • 您不能使用本地化偏移量 O,因为在 DateTimeFormatter 中它不支持您的 String 所具有的格式,即 GMT+0200 和格式化程序仅支持 GMT+8; GMT+08:00; UTC-08:00;(注意冒号)。使用转义 GMT 和常规偏移符号 x
  • 的组合
  • 您有一个 d,但表示天数总是两位数,因此您需要使用 dd
  • 你必须转义区域缩写所包含的括号,我认为一个 z 就足够了这样的缩写

考虑到所有这些方面,您可以按如下方式解析 String

public static void main(String[] args) {
    String parsePattern = "EEE MMM dd yyyy HH:mm:ss 'GMT'x '('z')'";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePattern,
                                                                Locale.ENGLISH);
    ZonedDateTime zdt = ZonedDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
    System.out.println(zdt);
}

然后输出(使用 ZonedDateTime 的默认格式化程序)

2020-02-04T16:11:25+02:00[Asia/Jerusalem]

这里的问题是 GMT+0200 如果您使用:GMT+02 它有效。 但是正如评论中已经提到的,您在 LocalDate 类型的对象上使用名为 dateTime 的变量有点令人困惑。 所以你的结果只会是日期2020-02-04因为LocalDate只能保存这种数据

以下模式有效。

"E MMM d u H:m:s 'GMT'Z (z)"

您可以将 Z 替换为 xX 以获得相同的结果。

如果你愿意,你可以拼写出来,但这不是必需的。

"EEE MMM dd uuuu HH:mm:ss 'GMT'ZZZ (zzz)"

您应该将该输入解析为 OffsetDateTime,因为输入字符串包括日期、时间、 偏移量。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM d u H:m:s 'GMT'Z (z)", Locale.ENGLISH);
OffsetDateTime dateTime = OffsetDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);
System.out.println(dateTime);

输出

2020-02-04T16:11:25+02:00

2 件事 - ZonedDateTime 和缺少“:”表示 0

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss O (zzz)");
ZonedDateTime dateTime = ZonedDateTime.parse("Tue Feb 04 2020 16:11:25 GMT+02:00 (IST)", formatter);

这应该有效

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM d yyyy HH:mm:ss 'GMT'Z (z)", Locale.ENGLISH);
        LocalDate dateTime = LocalDate.parse("Tue Feb 04 2020 16:11:25 GMT+0200 (IST)", formatter);

不要为时区使用固定文本:

不要像现有答案中提到的那样为时区使用固定文本(例如 'GMT'),因为该方法对于其他语言环境可能会失败。

推荐方案:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "Tue Feb 04 2020 16:11:25 GMT+0200 (IST)";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM d u H:m:s VVZ (z)", Locale.ENGLISH);
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);
    }
}

输出:

2020-02-04T14:11:25Z[Atlantic/Reykjavik]

ONLINE DEMO

Trail: Date Time.

了解有关现代日期时间 API 的更多信息