[java] JSON date to Java date?

I could not find this anywhere. I fetch some JSON from an API that returns standard JSON dates. You can see the format by running this code in a JavaScript console:

> new Date().toJSON();
"2010-10-27T11:58:22.973Z"

Well, actually, the API I'm working with is not returning the millisecond part, and sometimes it returns a timezone instead of Z, so dates can look like any one of these:

  • 2010-10-27T11:58:22Z
  • 2010-10-27T11:58:22+03:00

Parsing these kinds of dates is somewhat cumbersome. Is there any way to parse these kinds of dates, using org.json?

My current solution is:

public static Date parseDateTime(String dateString) {
    if (dateString == null) return null;
    DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
    if (dateString.contains("T")) dateString = dateString.replace('T', ' ');
    if (dateString.contains("Z")) dateString = dateString.replace("Z", "+0000");
    else
        dateString = dateString.substring(0, dateString.lastIndexOf(':')) + dateString.substring(dateString.lastIndexOf(':')+1);
    try {
        return fmt.parse(dateString);
    }
    catch (ParseException e) {
        Log.e(Const.TAG, "Could not parse datetime: " + dateString);
        return null;
    }
}

Ugh!

This question is related to java json

The answer is


Note that SimpleDateFormat format pattern Z is for RFC 822 time zone and pattern X is for ISO 8601 (this standard supports single letter time zone names like Z for Zulu).

So new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX") produces a format that can parse both "2013-03-11T01:38:18.309Z" and "2013-03-11T01:38:18.309+0000" and will give you the same result.

Unfortunately, as far as I can tell, you can't get this format to generate the Z for Zulu version, which is annoying.

I actually have more trouble on the JavaScript side to deal with both formats.


If you need to support more than one format you will have to pattern match your input and parse accordingly.

final DateFormat fmt;
if (dateString.endsWith("Z")) {
    fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
} else {
    fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
}

I'd guess you're dealing with a bug in the API you're using which has quoted the Z timezone date pattern somewhere...