javaandroiddatetime-parsingparseexception

Not able to convert the string to date on Android


I have obtained a string from an API in form of 2017-04-23T19:47:39+00:00 How do i convert it into date of format "2017-04-23T19:47:39-0000"?

I tried the following but it gave ParseException

String created_at_string = "2017-04-23T19:47:39+00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date created_at = sdf.parse(created_at_string);

Exception:

06-22 18:18:32.517 10396-10396/com.harit.abs W/System.err: java.text.ParseException: Unparseable date: ""2018-04-29T10:55:37+00:00""
        at java.text.DateFormat.parse(DateFormat.java:358)
        at com.harit.abs.Sync_Activity.bu(Sync_Activity.java:169)
        at com.harit.abs.Sync_Activity$2.onCompleted(Sync_Activity.java:118)
        at com.harit.abs.Sync_Activity$2.onCompleted(Sync_Activity.java:87)
        at com.koushikdutta.async.future.SimpleFuture.handleCallbackUnlocked(SimpleFuture.java:107)
        at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:141)
        at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:128)
        at com.koushikdutta.ion.IonRequestBuilder$1.run(IonRequestBuilder.java:246)
        at com.koushikdutta.async.AsyncServer$RunnableWrapper.run(AsyncServer.java:60)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)

Tried what is given in SimpleDateFormat with TimeZone Still getting the same parse Exception

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
String created_at_string = "2017-04-23T19:47:39+00:00";
Date created_at = sdf.parse(created_at_string);

Solution

  • You don’t need to

    The conversion you are asking about could easily be superfluous. You are asking for a string like 2017-04-23T19:47:39-0000. This string is in ISO 8601 format, the international standard format. So depending on your exact situation I would expect a string in ISO 8601 to be fine for you. The string you already got, 2017-04-23T19:47:39+00:00 is in ISO 8601 too! The standard allows for some variations, and one of them is that the colon in the offset is optional. So the first thing I think that you should do is to pass on the string you get and see if that works. In case it doesn’t, read on.

    java.time

    Your desired conversion goes so smoothly with java.time the modern Java date and time API:

        DateTimeFormatter formatterWithoutColon 
                = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssxx");
        String createdAtString = "2017-04-23T19:47:39+00:00";
        OffsetDateTime dateTime = OffsetDateTime.parse(createdAtString);
        String inDesiredFormat = dateTime.format(formatterWithoutColon);
        System.out.println(inDesiredFormat);
    

    This prints the desired:

    2017-04-23T19:47:39+0000

    Please note that we didn’t even need a formatter for parsing the string. OffsetDateTime and many other classes of java.time parse ISO 8601 as their default. Since our requirements for the result are a bit more precise, we use a formatter here. xx gives us the offset without colon, for example +0000.

    The Date class that you used is long outdated. So is SimpleDateFormat, and it’s notoriously troublesome too. I suggest you avoid those classes.

    Question: Can I use java.time on Android?

    Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.

    The hack

    The change you require is very simple, you just want a colon removed. So another, not so nice, but basic and simple solution that doesn’t require ThreeTenABP is a regular expression:

        String inDesiredFormat = createdAtString.replaceFirst("([+-]\\d{2}):(\\d{2})$", "$1$2");
    

    This gives the same result as above.

    Links