0

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?

4
  • Your date string has a space at the end? Just wondering. Of course it can still be parsed. Commented Nov 17, 2017 at 20:41
  • Does your code compile? date is declared a String, and a String doesn’t have a getTime method, but your last code line tries to call one. Commented Nov 17, 2017 at 20:45
  • Any particular reason why you are still using SimpleDateFormat? I consider it long outdated, and judging from the number of questions on Stack Overflow, it is causing trouble for many. java.time, the modern Java date and time API also known as JSR-310, is much nicer to work with. Commented Nov 17, 2017 at 20:47
  • Is there a misunderstanding here? Your said “to a new Date with time-Zone”. A Date never has got a time zone. See All about java.util.Date. Commented Nov 18, 2017 at 12:32

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.