0

I'm using GSON to convert JSONArray to Java objects. I need to convert both long date and simple date format "yyyy-MM-dd'T'HH:mm'Z'" to Java objects. I'm able to convert alone long or simple date but couldn't able to convert both together.

used below code snippet for long conversion :

GsonBuilder builder = new GsonBuilder();

    // Register an adapter to manage the date types as long values
    builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
            return new Date(json.getAsJsonPrimitive()
                    .getAsLong());
        }
    });

    Gson gson = builder.create();

    Type userListType = new TypeToken<ArrayList<CurrentLocation>>() {
    }.getType();

    gson.fromJson(data, userListType);

Sample data I need to convert :

[
  {
    "instance": {
      "location": {
        "lat": 31.522291,
        "lon": -96.532816,
        "timestamp": 1587693720000
      },
      "timeAtLocation": "2020-04-23T04:59Z"
    }
  },
  {
    "instance": {
      "location": {
        "lat": 31.522291,
        "lon": -96.532816,
        "timestamp": 1737693720000
      },
      "timeAtLocation": "2020-0-23T04:59Z"
    }
  }
]
Smile
  • 3,832
  • 3
  • 25
  • 39
Dev
  • 15
  • 3
  • Please take a look at this https://stackoverflow.com/questions/15563155/gson-to-json-conversion-with-two-dateformat – silentsudo Apr 30 '20 at 18:33
  • Thanks for sharing that, already seen that. Its not working in my case. As once I need to convert as long another case as date like return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString()); In that example, he as 2 date formats, but her one is long and other is date format. – Dev May 01 '20 at 06:36
  • you can stream data then convert timestamp to timezon string if you are 8using RxJava – silentsudo May 01 '20 at 06:53
  • I need to use timestamp value as it is, if I convert to timezone, that format will change. – Dev May 01 '20 at 07:52
  • I need to convert "timestamp":1587693720000 and "timeAtLocation":"2020-04-23T04:59Z" – Dev May 01 '20 at 08:14
  • I have added answer please check. – silentsudo May 01 '20 at 08:24

1 Answers1

1

Please try following code:

public class Main {

    static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm'Z'";
    static final Calendar calendar = Calendar.getInstance();

    static class LongUtil {
        static boolean isLong(String longValue) {
            try {
                Long.parseLong(longValue);
                return true;
            } catch (RuntimeException e) {
                return false;
            }

        }
    }

    static class DateDeserializer implements JsonDeserializer<Date> {

        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);

        @Override
        public Date deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
            System.out.println(type.getTypeName());
            System.out.println(jsonElement.getAsJsonPrimitive());
            if (jsonElement.getAsJsonPrimitive() != null) {
                final String expectedDateValue = jsonElement.getAsJsonPrimitive().getAsString();
                if (LongUtil.isLong(expectedDateValue)) {
                    System.out.println("It is long value hence parsing it to long");

                    calendar.setTimeInMillis(Long.parseLong(expectedDateValue));
                    return calendar.getTime();
                } else {
                    System.out.println("It is dateformat value hence parsing it to dateformat");
                    try {
                        return simpleDateFormat.parse(expectedDateValue);
                    } catch (ParseException e) {
                        throw new JsonParseException("Invalud dateFormat while parsing");
                    }
                }
            } else {
                throw new JsonParseException("JSOn Premitive Exception null");
            }
        }
    }

    public static void main(String[] args) throws IOException {
        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Date.class, new DateDeserializer());
        Gson gson = builder.create();
        Type userListType = new TypeToken<ArrayList<Wrapper>>() {
        }.getType();
        File file = new File("response.json");
        System.out.println("file exists : " + file.exists());
        JsonReader jsonReader = new JsonReader(new FileReader(file));

        List<Wrapper> wrapper = gson.fromJson(jsonReader, userListType);

        System.out.println(wrapper);
    }

    class Wrapper {
        User instance;

        @Override
        public String toString() {
            return "Wrapper{" +
                    "instance=" + instance +
                    '}';
        }
    }

    class User {
        Location location;
        Date timeAtLocation;


        @Override
        public String toString() {
            return "User{" +
                    "location=" + location +
                    ", timeAtLocation='" + timeAtLocation + '\'' +
                    '}';
        }
    }


    class Location {
        String lat;
        String lon;
        Date timestamp;

        @Override
        public String toString() {
            return "Location{" +
                    "lat='" + lat + '\'' +
                    ", lon='" + lon + '\'' +
                    ", timestamp='" + timestamp + '\'' +
                    '}';
        }
    }
}

Explaination:

While deserializing i am checking if the input string is either in dateformat or in long and based on that I create the calendar instance, then i set long and finally get date object date otherwise just use the string and format it based on date formatter.

Output:

file exists : true
It is long value hence parsing it to long
It is dateformat value hence parsing it to dateformat
It is long value hence parsing it to long
It is dateformat value hence parsing it to dateformat
[Wrapper{instance=User{location=Location{lat='31.522291', lon='-96.532816', timestamp='Fri May 01 13:49:08 IST 2020'}, timeAtLocation='Thu Apr 23 04:59:00 IST 2020'}}, Wrapper{instance=User{location=Location{lat='31.522291', lon='-96.532816', timestamp='Fri Jan 24 10:12:00 IST 2025'}, timeAtLocation='Mon Dec 23 04:59:00 IST 2019'}}]
silentsudo
  • 6,730
  • 6
  • 39
  • 81
  • note that i have changes some long value hence your output might vary :) – silentsudo May 01 '20 at 08:25
  • Thanks for the solution, I have tweaked it, its working fine. I'm using customized date format and Date so, kept 2 builders. builder.registerTypeAdapter(Date.class, new JsonDeserializer() { public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { return new Date(json.getAsJsonPrimitive() .getAsLong()); } }); builder.registerTypeAdapter(CustomDate.class, new DateDeserializer()); – Dev May 01 '20 at 10:38