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

添加Date类型TypeConverter后Room无法存储API返回结果

问题核心原因及修复方案

你遇到的问题由三个常见的低级错误共同导致,按优先级修复即可:

1. 日期格式符使用错误

你代码里的SimpleDateFormat用了YYYY模式符,这是JDK定义的周年计算规则,和日常使用的公历年逻辑完全不同,大概率会解析失败返回null,需要替换为小写的yyyy,同时建议指定时区和Locale避免多设备适配问题:

import androidx.room.TypeConverter
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*

class Converters {
    // 固定格式与时区,避免不同设备解析差异
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).apply {
        timeZone = TimeZone.getTimeZone("GMT+8") // 替换为你接口对应的时区
    }

    @TypeConverter
    fun fromTimestampStr(timeStamp: String?): Date? {
        return timeStamp?.let {
            try {
                dateFormat.parse(it)
            } catch (e: ParseException) {
                e.printStackTrace()
                null
            }
        }
    }

    @TypeConverter
    fun toTimestampStr(date: Date?): String? {
        return date?.let { dateFormat.format(it) }
    }
}

2. Gson未配置日期解析适配器

你之前用String?类型的时候API返回的字符串可以直接被Gson解析,改为Date?类型后,Gson默认没有内置对应格式的字符串转Date的适配器,API返回数据解析阶段dateAdded就已经是null了,不是Room不存,是你要存的对象本身该字段就为空。
在构造Retrofit的Gson转换器时添加日期格式配置即可:

val gson = GsonBuilder()
    .setDateFormat("yyyy-MM-dd HH:mm:ss")
    .create()

val retrofit = Retrofit.Builder()
    .baseUrl(你的接口根地址)
    .addConverterFactory(GsonConverterFactory.create(gson))
    // 其他配置
    .build()

3. 数据库结构变更未升级版本

你修改了表字段类型后,数据库版本号仍为1,如果你的设备上之前已经安装过旧版应用、存在旧数据库文件,Room检测到结构不匹配又没有迁移规则时会静默写入失败。
开发阶段可以直接升级版本号加销毁重建配置,避免迁移麻烦:

// 数据库版本号从1改为2
@Database(
    entities = arrayOf(
        Cocktail::class,
        CocktailRecipe::class,
        CocktailIngredient::class,
        IngredientType::class,
        Lists::class,
        ListsDrinksItems::class
    ),
    version = 2,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class GoodCallDatabase : RoomDatabase() {
    // 原有逻辑不变
    private fun buildDatabase(context: Context) = Room.databaseBuilder(
        context.applicationContext,
        GoodCallDatabase::class.java,
        "goodcalldatabase.db"
    )
        .fallbackToDestructiveMigration() // 开发阶段加这行,结构变更直接清空旧数据库重建
        .build()
}

验证方法

修复后在调用DAO存入Cocktail对象前打个断点,确认dateAdded字段已经被正确解析为非null的Date对象即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:24:01