简体   繁体   中英

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 . java.time , the modern Java date and time API also known as JSR-310 is generally so much nicer to work with. 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).

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.

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”). 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:

    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. 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. And anyway atZone() still sets the correct time zone.

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.

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. You'd need something like +0000 at the end.

If you want the string to be parsed correctly it must match the SimpleDateFormat pattern you supplied in the constructor:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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