-1

I need to convert Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time) to date. But I am getting

java.text.ParseException: Unparseable date: "Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)" exception

I tried like :

SimpleDateFormat formatter = new SimpleDateFormat("E MMM dd hh:mm:ss Z yyyy");
seenukarthi
  • 8,241
  • 10
  • 47
  • 68
  • 1
    Well, the `yyyy` is in the wrong part of your pattern, and the `(India Standard Time)` part needs to be taken out, as it's not a part of a date pattern. – Kayaman Sep 09 '19 at 09:26
  • 1
    I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `ZonedDateTime` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Sep 09 '19 at 09:42

2 Answers2

2

java.time

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            "EEE MMM dd uuuu HH:mm:ss 'GMT'xx (zzzz)", Locale.ENGLISH);
    String str = "Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)";
    TemporalAccessor parsed = formatter.parse(str);
    ZonedDateTime zdt = ZonedDateTime.from(parsed);
    // Check the offset against the time zone for validation
    ZoneOffset offset = ZoneOffset.from(parsed);
    if (offset.equals(zdt.getOffset())) {
        System.out.println(zdt);
    } else {
        System.err.println("Offset doesn’t match");
    }

Output from this snippet is:

2019-09-14T00:00+05:30[Asia/Kolkata]

Don’t use SimpleDateFormat and Date. Thise classes are poorly designed and long outdated. Instead I am using java.time, the modern Java date and time API. It is so much nicer to work with.

Validation is king. If one day you receive a string where the offset (like +0530 or -0400) does not agree with the time zone (like India Standard Time or Australian Central Daylight Time), you will want to discover and take appropriate action. I am therefore taking the offset out from the parsed date-time and comparing it with the offset that Java derives from the time zone. In this case they did agree. If it wasn’t for the need for this validation, the normal way to parse a ZonedDateTime would be the briefer:

    ZonedDateTime zdt = ZonedDateTime.parse(str, formatter);

Specify locale. Sat, Sep and India Standard Time are in English. If you don’t make sure that an English-speaking locale is used for parsing, parsing may well fail. If not today, then one day when you run your program on a computer with a different locale setting.

What went wrong in your code?

There are a couple of errors in your format pattern string. While the error message you got from SimpleDateFormat is quite general, java.time is sometimes more helpful. Let’s see if it can help us here. Using your format pattern string:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd hh:mm:ss Z yyyy", Locale.ENGLISH);
    ZonedDateTime zdt = ZonedDateTime.parse(str, formatter);

This gets us a

java.time.format.DateTimeParseException: Text 'Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)' could not be parsed at index 13

Index 13 is already something. Index 13 in your string is where the 19 in 2019 is. The parse method uses your format pattern for parsing the string and has successfully parsed Sat Sep 14 20 because it matched E MMM dd hh. It knows that an hour can only be 2 digits, so parses only 20 as hour and then objects because the format pattern specifies a colon after the hour, and there isn’t any colon after 20. You may have seen now that we should have specified a year ( uuuu or yyyy) after dd in the format pattern. Let’s repair, moving the yyyy in the string:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss Z", Locale.ENGLISH);

java.time.format.DateTimeParseException: Text 'Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)' could not be parsed at index 25

We’re about double as far. Index 25 is where GMT+0530 is. So this doesn’t match format pattern letter Z. The documentation says that Z is for zone offset, for example +0000; -0800; -08:00. Your string had GMT in front of the offset. We solve it by escaping it as literal text enclosing it in single quote:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss 'GMT'Z", Locale.ENGLISH);

java.time.format.DateTimeParseException: Text 'Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)' could not be parsed, unparsed text found at index 33

Index 33 is the space after GMT+0530. Your format pattern string ends here. There is a way to instruct the parsing to parse only as much of the string as it can, but that would deprive us of the validation of the time zone, so let’s not resort to that. Lowercase z is for time zone name:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss 'GMT'Z (zzzz)", Locale.ENGLISH);

java.time.format.DateTimeParseException: Text 'Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {NanoOfSecond=0, MinuteOfHour=0, MilliOfSecond=0, MicroOfSecond=0, OffsetSeconds=19800, HourOfAmPm=0, SecondOfMinute=0},ISO,Asia/Kolkata resolved to 2019-09-14 of type java.time.format.Parsed

This is a new one. The detail to notice is HourOfAmPm=0. We didn’t intend to put an hour within AM or PM in the string, just an hour of day. The error is lowercase hh for hour. For hour of day from 00 through 23 we need uppercase HH:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ss 'GMT'Z (zzzz)", Locale.ENGLISH);

Now parsing succeeds and gives the same result as above. What I wanted to say is that java.time is trying quite much harder to help us get the format pattern right.

Links

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

Please use the below-suggested date format which is working fine

String str = "Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)";
DateFormat inputFormat = new SimpleDateFormat(
        "E MMM dd yyyy HH:mm:ss 'GMT'z", Locale.ENGLISH);
Date date = inputFormat.parse(str);

Dinesh K
  • 269
  • 2
  • 8