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

Swift将ISO8601格式字符串转Date并输出time ago相对时间方案

问题根因

转换返回nil由两个配置错误导致:

  • 格式字符串不匹配:API返回的2021-07-07T15:03:21.409Z为带毫秒的ISO8601标准UTC时间,原配置的yyyy-MM-dd HH:mm:ss缺少T分隔符、.SSS毫秒位、Z时区标识的匹配规则
  • 时区配置错误:时间后缀的Z代表UTC时区,原代码强制设置为巴黎时区,时区不匹配导致解析失败
  • 附加隐性问题:原代码使用了系统默认locale,当用户系统语言为非拉丁语系时可能出现解析失败的兼容问题
修复代码

直接替换String扩展即可,也可保留通用转换方法适配其他场景:

extension String {
    // 专门适配当前API返回的ISO8601格式时间
    func toISO8601Date() -> Date? {
        let dateFormatter = DateFormatter()
        // 固定locale为en_US_POSIX避免系统语言影响解析
        dateFormatter.locale = Locale(identifier: "en_US_POSIX")
        // 对应Z标识的UTC时区
        dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
        dateFormatter.calendar = Calendar(identifier: .gregorian)
        // 完全匹配API返回格式的格式串
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        return dateFormatter.date(from: self)
    }
}
  • 补充优化:如果App最低支持iOS 10+/macOS 10.12+,更推荐使用系统自带的ISO8601解析器,无需手动维护格式串,兼容性更强:
extension String {
    func toISO8601Date() -> Date? {
        let formatter = ISO8601DateFormatter()
        formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
        return formatter.date(from: self)
    }
}
完整转换流程

修复后即可直接调用原有相对时间转换方法,完成完整流程:

// 示例API返回的时间字符串
let createTimeStr = "2021-07-07T15:03:21.409Z"
// 第一步:字符串转Date
guard let createDate = createTimeStr.toISO8601Date() else {
    // 此处添加解析失败的兜底逻辑,比如展示原始时间字符串
    return
}
// 第二步:Date转相对时间字符串
let displayTime = createDate.timeAgoDisplay()
// 可直接使用displayTime做UI展示

你原有提供的timeAgoDisplay扩展无需修改,Date解析正确后即可正常输出相对时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 01:36:03