0

I have a problem to parse my date from string

This is my date

String startedFrom = "Fri,+31+Dec+3999+23:00:00+GMT"

DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy kk:mm:ss z", Locale.ENGLISH);

Date result =  df.parse(startedFrom);

what I am doing wrong?

I get exception

java.text.ParseException: Unparseable date: "Fri,+31+Dec+3999+23:00:00+GMT"
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
mbrc
  • 3,523
  • 13
  • 40
  • 64
  • Don’t use the `SimpleDateFormat` class for this, it is not only long outdated, it’s also proven troublesome to work with. Instead I recommend you use [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jan 19 '18 at 09:54

2 Answers2

1
DateFormat df = new SimpleDateFormat("EEE,'+'dd'+'MMM'+'yyyy'+'kk:mm:ss'+'z",
        Locale.ENGLISH);

However if the startedFrom value is actually an URL encoded parameter added to an URL (as in a HTML form with GET method), then '+' would arrive as space ' ', hence your original format would be correct.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • 1
    Use ' ' to separate the dd mmm yyyy . Put + inside single quotes . df = new SimpleDateFormat("E, '+'dd'+'MMM'+'yyyy'+'kk:mm:ss'+'z"); also you can replace all + with space and then pass it to formatter – UmaShankar Chaurasiya Jan 19 '18 at 07:10
  • 1
    @Sweeper, yes single quotes are especially for letters that should not be interpreted as format placeholders. Thanks, I was not sure about `+`. Learned something. – Joop Eggen Jan 19 '18 at 07:20
1

First, do use java.time and its DateTimeFormatter class for this. SimpleDateFormat is notoriously troublesome and is long outdated along with the Date class. java.time is the modern Java date and time API and is so much nicer to work with.

Second, Joop Eggen is correct in his answer that your string looks like a URL encoded parameter that was originally Fri, 31 Dec 3999 23:00:00 GMT. This sounds even more likely as this is a standard format known as RFC 1123 and commonly used with HTTP. So your library for getting your URL parameters should URL decode the string for you. Then it’s straightforward since the formatter to use has already been defined for you:

    String startedFrom = "Fri, 31 Dec 3999 23:00:00 GMT";
    OffsetDateTime result 
            = OffsetDateTime.parse(startedFrom, DateTimeFormatter.RFC_1123_DATE_TIME);
    System.out.println(result);

This prints

3999-12-31T23:00Z

If you cannot get your library to URL decode, do it yourself by using URLDecoder:

    String startedFrom = "Fri,+31+Dec+3999+23:00:00+GMT";
    try {
        startedFrom = URLDecoder.decode(startedFrom, StandardCharsets.UTF_16.name());
    } catch (UnsupportedEncodingException uee) {
        throw new AssertionError("UTF_16 is not supported — this should not be possible", uee);
    }

Now proceed as above.

You may of course also define a formatter to parse the string with the pluses in it. I don’t know why you should want to, though. If you do, you just need to have them in the format pattern string too:

    DateTimeFormatter formatterWithPluses
            = DateTimeFormatter.ofPattern("EEE,+d+MMM+yyyy+H:mm:ss+z", Locale.ROOT);
    ZonedDateTime result = ZonedDateTime.parse(startedFrom, formatterWithPluses);

This time we got a ZonedDateTime with GMT as the name of the time zone:

3999-12-31T23:00Z[GMT]

Depending on what you need the date-time for, you may convert it to OffsetDateTime or Instant by calling result.toOffsetDateTime() or result.toInstant().

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161