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

Android Retrofit日期解析失败求助:无法解析"2018-05-09"格式

问题原因分析

你遇到的OnErrorNotImplementedException本质上是由ParseException引发的——Retrofit在解析JSON响应里的startConnection字段时,没法把字符串"2018-05-09"转换成Date类型。

具体来说,默认情况下(假设你用Gson作为Retrofit的JSON转换器),Gson解析Date类型依赖JDK默认的日期格式(一般是EEE MMM dd HH:mm:ss zzz yyyy这种带时间、时区的格式),但接口返回的是yyyy-MM-dd这种简化的日期格式,两者不匹配,所以抛出了解析异常。

另外,你的RxJava订阅只写了成功回调的Consumer,没处理错误回调,这也是最终抛出OnErrorNotImplementedException的原因——RxJava要求必须处理订阅过程中产生的错误,不然就会触发这个未实现错误的异常。

解决方案

下面是几种常用的解决办法,你可以根据自己用的JSON转换器选择:

方法一:自定义Gson日期格式(适用于Gson转换器)

如果用的是Gson,你需要创建一个自定义的Gson实例,指定日期解析格式,再把它配置到Retrofit中:

// 创建自定义Gson实例,匹配接口返回的日期格式
Gson gson = new GsonBuilder()
        .setDateFormat("yyyy-MM-dd")
        .create();

// 配置Retrofit时使用这个自定义Gson
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create(gson))
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build();

方法二:用注解指定单个字段的日期格式

如果你不想全局修改日期格式,只想给startConnection单独配置,可以用注解:

若使用Gson(需Gson 2.8+):

public class Device {
    private int id;
    private int phoneNumber;
    private String connectionName;
    private String deviceName;
    @DateFormat("yyyy-MM-dd") // 给该字段指定解析格式
    private Date startConnection;
    private Location actualLocation;
    private User owner;
    // getters、setters和构造方法
}

若使用Jackson:

public class Device {
    private int id;
    private int phoneNumber;
    private String connectionName;
    private String deviceName;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date startConnection;
    private Location actualLocation;
    private User owner;
    // getters、setters和构造方法
}

别忘了处理RxJava的错误回调

最后修改你的订阅代码,加上错误处理逻辑,避免再抛出OnErrorNotImplementedException:

public void getAllDevicesForCurrentUser(){
    compositeDisposable.add(restAPI.getDevices("Bearer " + TokenHolder.getInstance().getToken())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<List<Device>>() {
                @Override
                public void accept(List<Device> devices) throws Exception {
                    initializeDevices(devices);
                }
            }, new Consumer<Throwable>() { // 添加错误处理回调
                @Override
                public void accept(Throwable throwable) throws Exception {
                    // 这里可以打印日志、显示错误提示等
                    throwable.printStackTrace();
                }
            }));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:43:27