【问题标题】:ParseException while parsing date from String to date Object将日期从字符串解析为日期对象时出现 ParseException
【发布时间】:2018-01-30 09:34:46
【问题描述】:

我在解析从StringDate 对象的日期时得到一个ParseException。日期字符串还包含一个时区。我正在使用此代码:

final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
System.out.print(sdf.parse("2018-01-16T00:07:00.000+05:30"));

以下是我得到的错误:

Exception in thread "main" java.text.ParseException: Unparseable date: "2018-01-16T00:07:00.000+05:30"
    at java.text.DateFormat.parse(DateFormat.java:366)

【问题讨论】:

  • 日期字符串之间存在的TO呢???你也需要满足它。
  • 嗯...解析后的字符串是否遵循与格式说明符相同的格式?
  • 发生此异常是因为您与要解析的日期不匹配。
  • 试试这个链接中提供的答案:stackoverflow.com/questions/17692863/…
  • @srp321,在您链接的问题中找到的答案也使用SimpleDateFormat,我建议您避免使用java.time。在the answer by Laurent B 中查看现代且简单的解决方案。

标签: java date simpledateformat datetime-parsing parseexception


【解决方案1】:

您在SimpleDateFormat 中使用的格式必须与输入String 匹配。

您的输入是2018-01-16T00:07:00.000+05:30,即ISO8601 compliant

  • 年-月-日 (2018-01-16)
  • 后跟字母T
  • 后跟小时:分钟:秒.毫秒 (00:07:00.000)
  • 后跟UTC offset (+05:30)

注意:+05:30 的偏移量不是时区。 Read this 知道区别。

无论如何,您使用的模式 ("yyyy-MM-dd HH:mm:ss z") 与输入字符串不匹配:

  • 日期和时间之间缺少T
  • 它缺少毫秒数
  • 偏移前有一个空格
  • 解析偏移量的正确字母是 X(虽然我认为 z 可能有效,具体取决于您使用的 JVM 版本;在我的测试中,它没有)

所以你的代码应该是:

// use "XXX" to parse the whole offset (only one "X" will parse just `+05`, missing the `:30` part)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date d = sdf.parse("2018-01-16T00:07:00.000+05:30");

但最好使用新的 Java 8 类,如果它们可供您使用的话:

// parse ISO8601 compliant string directly
OffsetDateTime odt = OffsetDateTime.parse("2018-01-16T00:07:00.000+05:30");

如果您仍需要使用java.util.Date 对象,则很容易转换:

// convert to java.util.Date
Date date = Date.from(odt.toInstant());

【讨论】:

  • 很好解释的答案,谢谢。同意使用 Java 8 类。新的?只有四岁。 :-) 通过ThreeTen Backport 也可以在 Java 6 和 7 中使用。
【解决方案2】:

更改以下内容:

final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
          System.out.print(sdf.parse("2018-01-16 0:07:00 +0530"));

您正在尝试解析代表通用时区的 z,例如 GMT IST 等,但您需要 Z 时区偏移量,例如印度的 +0530。还要删除字符串之间的 OT。您的日期格式应与模式匹配。 参考https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

【讨论】:

  • RFC 822 是 ARPA Internet 文本消息规范。根据 ISO 8601,OP 使用的格式是正确的
  • @LaurentB 查看我的编辑..z 时区名称 zone-name 太平洋标准时间; PST while Z zone-offset offset-Z +0000; -0800; -08:00;这就是我想说的......这只是解决问题的另一种方法
【解决方案3】:

您使用的是 ISO 8601 日期。

使用 SimpleDateFormat :

final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSSX");
System.out.print(sdf.parse("2018-01-16T00:07:00.000+05:30"));

另外,您可以使用 ISO 8601 解析中提供的构建:

使用 joda 时间 Instant:

Instant.parse("2018-01-16T00:07:00.000+05:30")

JAVA 8 :(最好看下面的评论)

https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html#parse-java.lang.CharSequence-

    System.out.println(java.time.OffsetDateTime.parse(s));

【讨论】:

  • Instant.parse("2018-01-16T00:07:00.000+05:30") 不起作用,它会抛出 java.time.format.DateTimeParseException
  • @Rahul 在使用 joda 时进行了编辑,但 java 8 Instant 不支持时区,您必须使用 OffsetDateTime
  • 首选Java 8方案。 Joda-Time 处于维护模式,SimpleDateFormat 早已过时且出了名的麻烦。如果使用 Java 6 或 7,请考虑将 ThreeTen Backport 添加到您的项目中,以便您可以使用 Java 8 解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多