Retrofit GSON Date series from json string to long or java.lang.Long

I use the Retrofit library for my REST calls. The JSON that goes looks like this.

{ "created_at": "2013-07-16T22:52:36Z", } 

How can I tell Retrofit or Gson to convert this to long ?

+6
source share
7 answers

You can easily do this by installing a custom GsonConverter with your own Gson object on the modification instance. In your POJO you can Date created_at; instead of long or string. From a date object, you can use created_at.getTime() to get the length when necessary.

 Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ssz") .create(); RestAdapter.Builder builder = new RestAdapter.Builder(); // Use a custom GSON converter builder.setConverter(new GsonConverter(gson)); ..... create retrofit service. 

You can also support multiple date string formats by registering a custom JsonDeserializer in the gson instance used when modifying

 GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Date.class, new DateTypeDeserializer()); public class DateTypeDeserializer implements JsonDeserializer<Date> { private static final String[] DATE_FORMATS = new String[]{ "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd", "EEE MMM dd HH:mm:ss z yyyy", "HH:mm:ss", "MM/dd/yyyy HH:mm:ss aaa", "yyyy-MM-dd'T'HH:mm:ss.SSSSSS", "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS", "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'", "MMM d',' yyyy H:mm:ss a" }; @Override public Date deserialize(JsonElement jsonElement, Type typeOF, JsonDeserializationContext context) throws JsonParseException { for (String format : DATE_FORMATS) { try { return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString()); } catch (ParseException e) { } } throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString() + "\". Supported formats: \n" + Arrays.toString(DATE_FORMATS)); } } 
+18
source

Read it as a string in your POJO, then use your getter to return it as long:

 String created_at; public long getCreatedAt(){ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); Date createDate = formatter.parse(created_at); return createDate.getTime(); } 

the string SimpleDateFormat can be referenced here

+5
source

After reading the docs, I tried this. It works, but I do not know if this will affect other types.

I needed a long time in my POJO, because I do not want to convert when saving to db.

I used my own deserializer

 JsonDeserializer<Long> deserializer = new JsonDeserializer<Long>() { @Override public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try{ if(json==null){ return new Long(0); } else{ String dateString = json.getAsString(); long dateLong = DateFormatUtil.getLongServerTime(dateString); return new Long(dateLong); } } catch(ParseException e){ return new Long(0); } } }; 

and using it

 Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .setDateFormat(patternFromServer) .registerTypeAdapter(Long.class, deserializer) .create(); 
+2
source

You can simply use this setDateFormat() method to do this

 public class RestClient { private static final String BASE_URL = "your base url"; private ApiService apiService; public RestClient() { Gson gson = new GsonBuilder() .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'") .create(); RestAdapter restAdapter = new RestAdapter.Builder() .setLogLevel(RestAdapter.LogLevel.FULL) .setEndpoint(BASE_URL) .setConverter(new GsonConverter(gson)) .build(); apiService = restAdapter.create(ApiService.class); } public ApiService getApiService() { return apiService; } } 
+2
source

You can set the parsing template in GsonBuilder.setDateFormat() and set the Date object to POJO, and then just call Date.getMillis()

setDateFormat ()

0
source

You must use the type adapter in the Gson instance via

 new GsonBuilder() .registerTypeAdapter(Date.class, [date deserializer class here]) .create 

But can I assume that instead of using SimpleDateFormatter you look at this implementation from the FasterXML / jackson-databind implementations to handle the ISO8601 date in this class and this one . It very much depends on whether you sit a lot of chips or not.

Also note that we ran into problems using SimpleDateFormatter inside an Android application (we use a combination of Java and Android libraries), where there were different results between parsing in Java and Android. Using the above implementations helped solve this problem.

This is a Java implementation , and this is an Android implementation , not a definition for Z and X in a Java implementation and the missing X implementation in Android

0
source

Below code is tested and finally works after repeated attempts. Before creating a modified object, create a Gson object

  Gson gson = new GsonBuilder() .registerTypeAdapter(Date.class, new DateDeserializer()) .registerTypeAdapter(Date.class, new DateSerializer()) .create(); 

and now create an instance of the modified

 Retrofit retrofit retrofit = new Retrofit.Builder() .baseUrl("URL") .addConverterFactory(GsonConverterFactory.create(gson)) .build(); 

create these two classes for serializing and deserializing the date format

 static class DateDeserializer implements JsonDeserializer<Date> { private final String TAG = DateDeserializer.class.getSimpleName(); @Override public Date deserialize(JsonElement element, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { String date = element.getAsString(); SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); formatter.setTimeZone(TimeZone.getTimeZone("GMT")); Date returnDate = null; try { returnDate = formatter.parse(date); } catch (ParseException e) { Log.e(TAG, "Date parser exception:", e); returnDate = null; } return returnDate; } } static class DateSerializer implements JsonSerializer<Date> { private final String TAG = DateSerializer.class.getSimpleName(); @Override public JsonElement serialize(Date date, Type type, JsonSerializationContext jsonSerializationContext) { SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT); formatter.setTimeZone(TimeZone.getDefault()); String dateFormatAsString = formatter.format(date); return new JsonPrimitive(dateFormatAsString); } } 
0
source

Source: https://habr.com/ru/post/982550/


All Articles