简体   繁体   English

为什么我从SimpleDateFormat收到错误“无法解析的日期”?

[英]Why am i getting the error “Unparseable date” from SimpleDateFormat?

Im trying to parse a Date-String without timezone to a new Date with time-Zone but im getting the error: 我试图将不带时区的日期字符串解析为具有时区的新日期,但我收到错误:
java.text.ParseException: Unparseable date: "2017-11-17 10:49:39.772 "

Here´s my code: 这是我的代码:

 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();

Any suggestions? 有什么建议么?

Your question has been answered already. 您的问题已经回答。 I just wanted to contribute the modern version of your code. 我只是想贡献您的代码的现代版本。

java.time

Your are using the long outdated classes SimpleDateFormat and Date . 您正在使用过时的类SimpleDateFormatDate java.time , the modern Java date and time API also known as JSR-310 is generally so much nicer to work with. java.time ,现代Java日期和时间API(也称为JSR-310)通常更好用。 In your particular case the code is pretty similar: 在您的特定情况下,代码非常相似:

    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);

This prints 此打印

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

I need not repeat what @DarrenW already said: when your input string ends in a space and no time offset, then your format pattern string should also end in a space and no Z since Z matches an offset from UTC (now I repeated it anyway). 我不必重复@DarrenW已经说过的内容:当您的输入字符串以空格结尾且没有时间偏移时,那么您的格式模式字符串也应该以空格结尾且没有Z因为Z与UTC的偏移匹配(现在无论如何我都重复了它)。

Contrary to a Date a ZonedDateTime has a time zone in it (as the name says), so I was thinking this might fit your requirements better. Date相反, ZonedDateTime有一个时区(顾名思义),因此我认为这可能更适合您的要求。

Getting milliseconds from the epoch 从纪元获取毫秒

It may be speculation: your call date.getTime() gave me the impression that you're after the number of milliseconds since January 1, 1970, 00:00:00 GMT (the “epoch”). 可能是推测:您的调用date.getTime()给我的印象是您距格林尼治标准时间1970年1月1日00:00:00(“纪元”)以来的毫秒数。 If so, do: 如果是这样,请执行以下操作:

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

The result is 结果是

1510912179772

Parsing with a time zone offest in the string 用字符串中最远的时区进行解析

More speculation, I could not help thinking that what just might have happened was that you received a date-time string that matched your format pattern string, but with an incorrect time zone offset in, which you stripped off, leaving the dangling space in the end of your string. 更多的猜测是,我不禁会想, 可能是您收到了一个与格式模式字符串匹配的日期时间字符串,但是输入了不正确的时区偏移量,您将其剥离了,从而在其中留下了悬空的空间。字符串的结尾。 If this was the case, the modern API can handle the situation more easily and elegantly by just ignoring the incorrect offset while parsing: 如果是这种情况,现代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);

The result is 2017-11-17T10:49:39.772+01:00[Europe/Amsterdam] again, exactly the same as from the first snippet above. 结果2017-11-17T10:49:39.772+01:00[Europe/Amsterdam]2017-11-17T10:49:39.772+01:00[Europe/Amsterdam] ,与上面的第一个代码段完全相同。 LocalDateTime is a date and time without any time zone or offset information, so there is no way the incorrect offset from the string could come through. LocalDateTime是没有任何时区或偏移量信息的日期和时间,因此,无法通过字符串获得不正确的偏移量。 And anyway atZone() still sets the correct time zone. 无论如何, atZone()仍设置正确的时区。

Another way to obtain the same would be to parse right into a ZonedDateDate and then call its withZoneSameLocal() to get rid of the unwanted offset. 获得相同结果的另一种方法是将其解析为ZonedDateDate ,然后调用其withZoneSameLocal()来摆脱不需要的偏移量。

You explicitly said in your SimpleDateFormat that you require a timezone offset at the end (the Z parameter), yet your string is missing the offset. 您在SimpleDateFormat中明确表示要在末尾需要时区偏移量( Z参数),但是字符串缺少该偏移量。 You'd need something like +0000 at the end. 您最终需要+0000这样的东西。

If you want the string to be parsed correctly it must match the SimpleDateFormat pattern you supplied in the constructor: 如果要正确解析字符串,则它必须与构造函数中提供的SimpleDateFormat模式匹配:

Old line: 旧线:

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

New line: 新队:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM