I am using the Retrofit library for my REST calls. The JSON that is coming in looks like this.
{
"created_at": "2013-07-16T22:52:36Z",
}
How can I tell Retrofit or Gson to convert this into long?
I am using the Retrofit library for my REST calls. The JSON that is coming in looks like this.
{
"created_at": "2013-07-16T22:52:36Z",
}
How can I tell Retrofit or Gson to convert this into long?
You can easily do this by setting a custom GsonConverter with your own Gson object on the retrofit instance. In your POJO you can Date created_at;
instead of a long or a String. From the date object you can use created_at.getTime()
to get the long 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
on the gson instance used by retrofit
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));
}
}
Read it in as a string in your POJO then use your getter to return it as a 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 SimpleDateFormat string can be referenced here
DateFormat
vs SimpleDateFormat
I'd say try using SimpleDateFormat. –
Cardoza You could simply use this setDateFormat()
method to do it
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;
}
}
IllegalArgumentException: Unterminated quote
when initialized. You could have seen if you had tested it before posting –
Maggee After reading the docs, I tried this. It works but i dont know if it will have any effect on other types.
I needed to have a long in my POJO, coz i dont wanna convert when saving into db.
I used a custom 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();
Below code is tested and finally working after lot efforts. before creating retrofit object create Gson object
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateDeserializer())
.registerTypeAdapter(Date.class, new DateSerializer())
.create();
and now create retrofit instance
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("URL")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
create these two classes to serialize and deserialize 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);
}
}
You can set the parse pattern in the GsonBuilder.setDateFormat()
and set Date object in the POJO and then just call Date.getMillis()
You should be using a type adapter in your Gson
instance through
new GsonBuilder()
.registerTypeAdapter(Date.class, [date deserializer class here])
.create
But can I suggest that instead of using a SimpleDateFormatter you take a look at this implementation from FasterXML/jackson-databind implementations for ISO8601 date handling in this class and this one. It very much depends on whether you are parsing a lot of dates or not.
Also note that we ran into issues with 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 to solve this issue.
This is the Java implementation and this is the Android implementation, not the definition for Z
and X
in the Java implementation and the missing X
implementation in Android
© 2022 - 2024 — McMap. All rights reserved.
Z
looks strange. I would bet on a formatting issue on the server side. – SpearheadZ
simple means there is no offset from UTC - more info from wikipedia – Hilburn