如何将Flutter的toIso8601String输出转换为Swift可用的Date对象
问题根因
- 你传入的ISO8601字符串没有时区标识:Flutter本地时区的
DateTime调用toIso8601String()默认不会加时区后缀,而Swift的ISO8601DateFormatter默认要求字符串包含完整时区信息才能解析成功 - 配置的
formatOptions存在冗余冲突:.withInternetDateTime本身已经包含了日期分隔符、时间分隔符、完整日期等配置,重复添加可选参数反而可能导致解析逻辑异常 - Flutter输出的时间包含6位微秒精度小数,解析配置必须显式支持 fractional seconds 格式
解决方法
方案1:不修改Flutter端输出,适配现有字符串
如果确定Flutter输出的是当前设备本地时区的时间,直接用DateFormatter适配无后缀的格式即可:
let shared = sharedDefaults?.object(forKey: "widgetData") as? [String: String] ?? [String: String]() let dateFormatter = DateFormatter() // 适配6位微秒精度的无后缀ISO格式 dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS" // 和Flutter输出时间的时区保持一致,本地时间用current,UTC时间用GMT dateFormatter.timeZone = TimeZone.current // 固定locale避免系统地区/语言设置影响解析结果 dateFormatter.locale = Locale(identifier: "en_US_POSIX") let realDate = dateFormatter.date(from: shared["start"]!) flutterData = FlutterData(title: shared["title"]!, comment: shared["comment"]!, end: nil, start: realDate ?? Date())
方案2:修改Flutter端输出,使用标准ISO8601格式(更推荐)
从根源避免跨端时区不一致问题,Flutter侧输出时统一转成UTC时间带标准时区标识:
// Flutter 侧代码修改:输出带Z后缀的UTC标准ISO8601字符串 String isoDateStr = DateTime.now().toUtc().toIso8601String();
Swift侧简化解析配置即可:
let shared = sharedDefaults?.object(forKey: "widgetData") as? [String: String] ?? [String: String]() let isoDateFormatter = ISO8601DateFormatter() isoDateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] let realDate = isoDateFormatter.date(from: shared["start"]!) flutterData = FlutterData(title: shared["title"]!, comment: shared["comment"]!, end: nil, start: realDate ?? Date())
内容的提问来源于stack exchange,提问作者Moel
相关产品推荐
相关产品推荐

