57

I'm getting a date/time in json as 2011-10-26T20:29:59-07:00. What's the proper way to use gsonBuilder.setDateFormat to properly format this time?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
LuxuryMode
  • 33,401
  • 34
  • 117
  • 188

4 Answers4

105

The -07:00 is the ISO 8601 time zone notation. This is not supported by SimpleDateFormat until Java 7. So, if you can upgrade to Java 7, then you can use the X to represent that time zone notation:

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssX").create();

On Java 6 you would need to do some pattern matching and replacing on the JSON string first to replace the -07:00 part by the RFC 822 notation -0700 so that you can use Z:

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create();

or by the general time zone notation GMT-07:00 so that you can use z:

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssz").create();
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Helped me a lot thanks. Wish I have more than one upvotes. :) – ahmet alp balkan Dec 23 '11 at 11:37
  • you can see my answer below for a Java 6 solution with pattern matching. – JoeLallouz Nov 22 '12 at 17:45
  • 4
    Great answer, thanks. I used `Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").create();` to get milliseconds also. I have not found a way (other than using a custom adaptor) to support both formats. – Wim Fikkert Apr 08 '14 at 09:31
  • 2
    I'm using Java 8 (Android w/ Retrolambda), and I'm getting an error "java.lang.IllegalArgumentException: Unknown pattern character 'X'" – loeschg Dec 16 '14 at 18:18
  • There is no Java 8 on Android - here you're stuck with something like JDK6. – Boris Treukhov Sep 01 '15 at 12:20
  • On Java 6 it's possible to escape the Z character with single quote: `new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'").create()`. This way, no find and replace is needed – Crferreira Feb 07 '18 at 13:29
12

For Java 8 (have not verified for Java 7), just use the pattern

yyyy-MM-dd'T'HH:mm:ssXXX

To get exactly the format of 2011-10-26T20:29:59-07:00.

The time zone pattern is from Java Date Time - Custom Date Format Patterns

  • X
    Zone offset
    Example:
        X       +09
        XX      +0930 
        XXX     +09:30
        XXX     -05:00
        XXXX    +093045
        XXXXX   +08:30:45
    
Loki
  • 931
  • 8
  • 13
8

My api response date format is exactly same with yours, like this:

"weather": {
    "temperature": 31,
    "time": "2016-06-23T09:28:38+08:00"
}

in Android project, I use following code, both work for me.

Gson gson = new GsonBuilder()
       .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
       .create();

// or, also work
Gson gson = new GsonBuilder()
       .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
       .create();

"yyyy-MM-dd'T'HH:mm:ssX" doesn't work in Android, although I have configed use Java 8 in build.gradle.

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

how do we know the date format we should set, in fact you can find the answer from the source code of SimpleDateFormat.java:

 * <p>Which produces this output when run in the America/Los_Angeles time zone:
 * <pre>
 *                     yyyy-MM-dd 1969-12-31
 *                     yyyy-MM-dd 1970-01-01
 *               yyyy-MM-dd HH:mm 1969-12-31 16:00
 *               yyyy-MM-dd HH:mm 1970-01-01 00:00
 *              yyyy-MM-dd HH:mmZ 1969-12-31 16:00-0800
 *              yyyy-MM-dd HH:mmZ 1970-01-01 00:00+0000
 *       yyyy-MM-dd HH:mm:ss.SSSZ 1969-12-31 16:00:00.000-0800
 *       yyyy-MM-dd HH:mm:ss.SSSZ 1970-01-01 00:00:00.000+0000
 *     yyyy-MM-dd'T'HH:mm:ss.SSSZ 1969-12-31T16:00:00.000-0800
 *     yyyy-MM-dd'T'HH:mm:ss.SSSZ 1970-01-01T00:00:00.000+0000
 * </pre>
Spark.Bao
  • 5,573
  • 2
  • 31
  • 36
4

It's been a while since this was posted, but came accross it when trying to use GSON to parse an API response that had this date format. I figured I would share the 2 little functions I wrote using regex to find all the dates and change them to the format that GSON can then parse.

private static String cleanDateFormat(String json){ // takes in a string of JSON
    Pattern regex = Pattern.compile("\\d\\d:\\d\\d:\\d\\d[-\\+]\\d\\d:\\d\\d"); 
    Matcher regexMatcher = regex.matcher(json);
    StringBuffer buff = new StringBuffer();
    while(regexMatcher.find()){
        regexMatcher.appendReplacement(buff, getSubOfMatch(regexMatcher));
    }
    regexMatcher.appendTail(buff);
    return buff.toString();
}
//then pull out the colon.
private static String getSubOfMatch(Matcher matcher){
    StringBuilder sb = new StringBuilder(matcher.group(0));
    sb.deleteCharAt(sb.length()-3);
    return sb.toString();
}
JoeLallouz
  • 1,338
  • 1
  • 10
  • 14