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

Flutter加载本地数据库数据时String无法转DateTime异常如何解决

问题根因

你使用的本地NoSQL数据库(如sembast)本身不支持直接存储DateTime类型,写入数据时你已将DateTime转换为字符串(通常为ISO 8601格式)存储,读取时直接用as DateTime强转字符串类型的存储值,就会触发类型不匹配异常。

修复步骤
    1. 修正数据库读取时的日期字段解析逻辑
      将抛出异常的行替换为字符串转DateTime的逻辑,修改后的代码如下:
date: DateTime.parse(record['date'] as String),

如果你写入时存的是毫秒级时间戳,可替换为DateTime.fromMillisecondsSinceEpoch(record['date'] as int)即可。

    1. 优化方法返回类型,提升类型安全性
      你提问中提到的List transactionList = <Transactions>[];写法不是拷贝构造函数,只是声明了一个元素类型为Transactions的空列表。建议将loaddata方法的返回值从List<dynamic>改为明确的List<Transactions>,修改如下:
// 修改方法返回值类型
Future<List<Transactions>> loaddata() async {
    var db = await opendb();
    var store = intMapStoreFactory.store('expense');
    var snapshot = await store.find(db);
    // 简化列表声明
    final transactionList = <Transactions>[];
    for (var record in snapshot) {
      transactionList.add(Transactions(
          title: record['title'] as String,
          subtitle: record['subtitle'] as String,
          date: DateTime.parse(record['date'] as String)));
    }
    return transactionList;
}

修改后返回的列表可以直接用于页面渲染,无需额外类型转换。

    1. 同步修改Provider中的变量类型
      将TransactionProvider中的transactions变量类型从List<dynamic>改为List<Transactions>,避免后续使用时出现类型问题:
class TransactionProvider with ChangeNotifier {
  // 修改为明确类型
  List<Transactions> transactions = [];

  void addTransaction(Transactions statement) async {
    var db = TransactionDB(dbName: 'transactions.db'); 
    transactions = await db.loaddata();
    notifyListeners();
  }
}
补充注意

写入数据到数据库时,要保证和读取逻辑对应,需将DateTime转为ISO 8601字符串存储,示例如下:

await store.add(db, {
  'title': transaction.title,
  'subtitle': transaction.subtitle,
  'date': transaction.date.toIso8601String(),
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:15:00