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

如何将含自定义Event类的DateTime-List<Event> Map转为JSON?

解决Dart中Map<DateTime, List>的JSON序列化/反序列化问题

报错原因

json.encode只能处理Dart原生可序列化类型(比如字符串、数字、原生List/Map等),你的代码里两个关键点不符合要求:

  • Map的键是DateTime类型,JSON不支持非字符串作为键
  • Event是自定义类,默认没有实现序列化逻辑

解决方案步骤

1. 给Event类添加序列化/反序列化方法

修改Event类,增加toJson方法把对象转成可序列化的Map,再增加工厂方法fromJson把Map转回Event:

class Event {
  final String title;
  Event({required this.title});

  // 转成可序列化的Map
  Map<String, dynamic> toJson() {
    return {'title': title};
  }

  // 从Map转成Event对象
  factory Event.fromJson(Map<String, dynamic> json) {
    return Event(title: json['title'] as String);
  }

  @override
  String toString() => title;
}

2. 实现Map转JSON的逻辑

需要把原Map的DateTime键转成ISO格式字符串,同时把List<Event>转成List<Map>:

// 把Map<DateTime, List<Event>>转成可序列化的Map<String, List<Map>>
Map<String, dynamic> convertSelectedEventsToJson(Map<DateTime, List<Event>> events) {
  return events.map((key, value) => MapEntry(
        key.toIso8601String(), // DateTime转ISO字符串作为键
        value.map((event) => event.toJson()).toList(), // 每个Event转成Map
      ));
}

// 使用示例
final jsonString = json.encode(convertSelectedEventsToJson(selectedEvents!));
print(jsonString);

3. 实现JSON转回Map的逻辑

把JSON里的字符串键转回DateTime,同时把List<Map>转回List<Event>:

// 把JSON字符串转回Map<DateTime, List<Event>>
Map<DateTime, List<Event>> convertJsonToSelectedEvents(String jsonString) {
  final jsonMap = json.decode(jsonString) as Map<String, dynamic>;
  return jsonMap.map((key, value) => MapEntry(
        DateTime.parse(key), // 字符串转DateTime
        (value as List).map((item) => Event.fromJson(item as Map<String, dynamic>)).toList(), // Map转Event
      ));
}

// 使用示例
final restoredEvents = convertJsonToSelectedEvents(jsonString);

完整测试代码

import 'dart:convert';

class Event {
  final String title;
  Event({required this.title});

  Map<String, dynamic> toJson() {
    return {'title': title};
  }

  factory Event.fromJson(Map<String, dynamic> json) {
    return Event(title: json['title'] as String);
  }

  @override
  String toString() => title;
}

void main() {
  // 模拟有数据的selectedEvents
  final selectedEvents = <DateTime, List<Event>>{
    DateTime.now(): [Event(title: '会议'), Event(title: '健身')],
  };

  // 转JSON
  final jsonMap = selectedEvents.map((key, value) => MapEntry(
        key.toIso8601String(),
        value.map((e) => e.toJson()).toList(),
      ));
  final jsonString = json.encode(jsonMap);
  print('序列化后的JSON: $jsonString');

  // 反序列化回原Map
  final decodedMap = json.decode(jsonString) as Map<String, dynamic>;
  final restoredEvents = decodedMap.map((key, value) => MapEntry(
        DateTime.parse(key),
        (value as List).map((item) => Event.fromJson(item as Map<String, dynamic>)).toList(),
      ));
  print('反序列化后的Map: $restoredEvents');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:22:15