为什么我从SimpleDateFormat收到错误“Unparseable date”?

时间:2017-11-17 17:08:45

标签: java timestamp simpledateformat

我试图将没有时区的日期字符串解析为带有时区的新日期但我得到错误:
java.text.ParseException: Unparseable date: "2017-11-17 10:49:39.772 "

这是我的代码:

 String date = "2017-11-17 10:49:39.772 "
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z");
 sdf.setTimeZone(TimeZone.getTimeZone("Europe/Amsterdam"));
 sdf.parse(date);  //here´s the error
 return date.getTime();

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

您的问题已经回答了。我只想提供代码的现代版本。

<强> java.time

您使用的是过期的较长的课程SimpleDateFormatDatejava.time,现代Java日期和时间API(也称为JSR-310)通常可以更好地使用。在您的特定情况下,代码非常相似:

    String date = "2017-11-17 10:49:39.772 ";
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS ");
    ZoneId zid = ZoneId.of("Europe/Amsterdam");
    ZonedDateTime zdt = LocalDateTime.parse(date, dtf).atZone(zid);
    System.out.println(zdt);

打印

2017-11-17T10:49:39.772+01:00[Europe/Amsterdam]

我不需要重复@DarrenW已经说过的内容:当你的输入字符串以空格结尾而没有时间偏移时,那么你的格式模式字符串也应该以空格结尾而不是Z,因为Z匹配UTC的偏移量(现在我反复重复)。

Date相反,ZonedDateTime中有一个时区(如名称所示),所以我认为这可能更符合您的要求。

从纪元获取毫秒

可能是猜测:你的电话date.getTime()让我觉得你是在1970年1月1日00:00:00(格林威治标准时间)之后的毫秒数。如果是这样,请执行:

    long millisSinceEpoch = zdt.toInstant().toEpochMilli();

结果是

1510912179772

在字符串

中解析时区offest

更多猜测,我不禁想到可能发生的事情是你收到的日期时间字符串与你的格式模式字符串相匹配,但时区偏移量不正确,你脱掉了,把悬空空间留在你的弦的尽头。如果是这种情况,那么现代API可以通过在解析时忽略不正确的偏移量来更轻松,更优雅地处理这种情况:

    String date = "2017-11-17 10:49:39.772 +0000";
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS Z");
    ZoneId zid = ZoneId.of("Europe/Amsterdam");
    ZonedDateTime zdt = LocalDateTime.parse(date, dtf).atZone(zid);

结果再次为2017-11-17T10:49:39.772+01:00[Europe/Amsterdam],与上面的第一个代码段完全相同。 LocalDateTime是没有任何时区或偏移信息的日期和时间,因此不能通过字符串的不正确偏移来实现。无论如何atZone()仍设置正确的时区。

获得相同内容的另一种方法是直接解析为ZonedDateDate,然后调用其withZoneSameLocal()以消除不需要的偏移量。

答案 1 :(得分:1)

您在SimpleDateFormat中明确表示您需要在末尾添加时区偏移(Z参数),但您的字符串缺少偏移量。你最后需要+0000这样的东西。

答案 2 :(得分:1)

如果要正确解析字符串,它必须与构造函数中提供的SimpleDateFormat模式匹配:

旧行:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z");

新行:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ");