改造 GSON 将日期从 json 字符串序列化为 long 或 java.lang.Long
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28540224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Retrofit GSON serialize Date from json string into long or java.lang.Long
提问by user2524597
I am using the Retrofit library for my REST calls. The JSON that is coming in looks like this.
我正在使用 Retrofit 库进行 REST 调用。传入的 JSON 如下所示。
{
"created_at": "2013-07-16T22:52:36Z",
}
How can I tell Retrofit or Gson to convert this into long?
我如何告诉 Retrofit 或 Gson 将其转换为long?
回答by Aegis
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 对象设置自定义 GsonConverter 来轻松完成此操作。在您的 POJO 中,您可以Date created_at;
代替 long 或 String。从日期对象中,您可以created_at.getTime()
在必要时使用它来获取时间。
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
您还可以JsonDeserializer
通过在改造使用的 gson 实例上注册自定义来支持多种日期字符串格式
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));
}
}
回答by pula
Read it in as a string in your POJO then use your getter to return it as a long:
将其作为 POJO 中的字符串读入,然后使用 getter 将其作为 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
可以在此处引用 SimpleDateFormat 字符串
回答by user2524597
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.
我需要在我的 POJO 中有很长的时间,因为我不想在保存到 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();
回答by Gowtham Raj
You could simply use this setDateFormat()
method to do it
你可以简单地使用这种setDateFormat()
方法来做到这一点
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;
}
}
回答by Amol Suryawanshi
Below code is tested and finally working after lot efforts. before creating retrofit object create Gson object
下面的代码经过测试,经过大量努力终于可以工作了。在创建改造对象之前创建 Gson 对象
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);
}
}
回答by Phil H
You should be using a type adapter in your Gson
instance through
您应该通过在您的Gson
实例中使用类型适配器
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/Hymanson-databind implementations for ISO8601 date handling in this classand this one. It very much depends on whether you are parsing a lot of dates or not.
但我可以建议,而是采用了SimpleDateFormatter你看看从FasterXML /Hyman逊-数据绑定实现这个实现在ISO8601日期处理这一类和这一个。这在很大程度上取决于您是否正在解析大量日期。
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.
另请注意,我们在 Android 应用程序(我们使用 Java 和 Android 库的组合)中使用 SimpleDateFormatter 时遇到了问题,其中 Java 和 Android 中的解析结果不同。使用上述实现有助于解决这个问题。
This is the Java implementationand this is the Android implementation, not the definition for Z
and X
in the Java implementation and the missing X
implementation in Android
这是Java 实现,这是Android 实现,而不是Java 实现中的和定义Z
以及Android 中X
缺失的X
实现。
回答by Towlie288
You can set the parse pattern in the GsonBuilder.setDateFormat()
and set Date object in the POJO and then just call Date.getMillis()
您可以GsonBuilder.setDateFormat()
在 POJO 中设置解析模式并在 POJO 中设置 Date 对象,然后调用Date.getMillis()