值1476399300000从
Unix epoch开始看起来像ms.只需在Gson中添加一个类型适配器:
final class UnixEpochDateTypeAdapter
extends TypeAdapter {
private static final TypeAdapter unixEpochDateTypeAdapter = new UnixEpochDateTypeAdapter();
private UnixEpochDateTypeAdapter() {
}
static TypeAdapter getUnixEpochDateTypeAdapter() {
return unixEpochDateTypeAdapter;
}
@Override
public Date read(final JsonReader in)
throws IOException {
// this is where the conversion is performed
return new Date(in.nextLong());
}
@Override
@SuppressWarnings("resource")
public void write(final JsonWriter out, final Date value)
throws IOException {
// write back if necessary or throw UnsupportedOperationException
out.value(value.getTime());
}
}
配置您的Gson实例:
final Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, getUnixEpochDateTypeAdapter())
.create();
Gson实例与UnixEpochDateTypeAdapter一样是线程安全的,并且可以作为一个全局实例存在.例:
final class Mapping {
final Date date = null;
}
final String json = "{\"date\":1476399300000}";
final Mapping mapping = gson.fromJson(json, Mapping.class);
System.out.println(mapping.date);
System.out.println(gson.toJson(mapping));
会给出以下输出:
Fri Oct 14 01:55:00 EEST 2016
{“date”:1476399300000}
请注意,类型适配器配置为覆盖默认的Gson日期类型适配器.因此,您可能需要使用更复杂的分析来检测是否只是Unix时代的ms.另请注意,您可以使用JsonDeserializer,但后者以JSON树方式工作,而类型适配器以流式方式工作,这种方式更有效,可能不会累积中间结果.
编辑:
此外,它可能看起来令人困惑,但Gson可以为原语进行值转换.尽管您的有效负载具有字符串值,但JsonReader.nextLong()可以将字符串原语读取为long值.所以UnixEpochDateTypeAdapter.write应该是out.value(String.valueOf(value.getTime()));为了不修改JSON文字.
编辑
还有一个更短的解决方案(使用JSON内存树而不是数据流),这简单:
final Gson builder = new GsonBuilder()
.registerTypeAdapter(Date.class, new JsonDeserializer() {
public Date deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
return new Date(jsonElement.getAsJsonPrimitive().getAsLong());
}
})
.create();