You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需自定义类,Retrofit+Gson解析特殊日期格式的方法咨询

解决Retrofit+Gson解析嵌套日期结构为java.util.Date的问题

嘿,这个场景我太熟悉了——默认的Gson日期格式处理确实搞不定这种嵌套的date/time结构,不用自定义类的话,咱们可以给Gson加个自定义日期反序列化器来解决,步骤很简单:

1. 编写自定义JsonDeserializer

创建一个实现JsonDeserializer<Date>的类,手动解析API返回的嵌套date和time字段,然后组装成java.util.Date对象:

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;

import java.lang.reflect.Type;
import java.util.Calendar;
import java.util.Date;

public class NestedDateDeserializer implements JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject rootObj = json.getAsJsonObject();
        
        // 解析date子对象
        JsonObject dateObj = rootObj.getAsJsonObject("date");
        int year = dateObj.get("year").getAsInt();
        int month = dateObj.get("month").getAsInt() - 1; // Calendar月份是0-based(0=1月)
        int day = dateObj.get("day").getAsInt();
        
        // 解析time子对象
        JsonObject timeObj = rootObj.getAsJsonObject("time");
        int hour = timeObj.get("hour").getAsInt();
        int minute = timeObj.get("minute").getAsInt();
        int second = timeObj.get("second").getAsInt();
        int nano = timeObj.get("nano").getAsInt();
        
        // 用Calendar组装日期时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, day, hour, minute, second);
        calendar.set(Calendar.MILLISECOND, nano / 1000000); // 纳秒转毫秒(Date只支持毫秒精度)
        
        return calendar.getTime();
    }
}

2. 注册反序列化器到GsonBuilder

把上面的自定义反序列化器注册到GsonBuilder中,替换原来的setDateFormat配置:

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

3. 集成到Retrofit

把这个自定义的Gson实例传给Retrofit的转换器即可:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("你的API基础地址")
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build();

额外说明

  • 如果你的项目用的是Java 8+,也可以用LocalDateTime替代Date,然后写对应的反序列化器,逻辑类似,只是用LocalDateTime.of()来组装时间。
  • 如果API返回的结构中date或time字段可能为null,记得在代码里加空判断,避免NullPointerException。

内容的提问来源于stack exchange,提问作者Ergin Ersoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:50:19