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

Swift字符串与日期互转方法及JSON时间戳格式化问题排查

嘿,我来帮你搞定这个Swift日期转换的问题!

Swift中字符串与日期的相互转换

先说说你的代码问题

你遇到的核心问题是formatter.date(from: date)返回了nil,所以才会 fallback 到当前日期。这是因为你设置的dateFormat和输入的ISO格式字符串完全不匹配!你输入的是2020-03-07T12:18:26.347Z这种带毫秒的UTC标准格式,但你的格式化器用的是d-M-y, HH:mm,系统根本没法解析,自然返回nil。

正确的实现方案

要处理这种ISO 8601格式的字符串,我们需要分两步走:

  1. 用匹配输入格式的工具把原始字符串解析成Date类型
  2. 再用另一个格式化器把Date转成用户友好的字符串

方法一:用ISO8601DateFormatter(推荐,简洁不易错)

苹果专门提供了处理ISO 8601格式的类,不用手动写复杂的dateFormat:

func convertISOToFriendlyDate(dateString: String) -> String {
    // 第一步:解析ISO格式字符串为Date
    let isoFormatter = ISO8601DateFormatter()
    // 开启毫秒解析支持(iOS 10+/macOS 10.12+可用)
    isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
    
    guard let date = isoFormatter.date(from: dateString) else {
        // 解析失败的 fallback,可根据需求调整
        return "无效日期"
    }
    
    // 第二步:格式化为用户友好的字符串
    let friendlyFormatter = DateFormatter()
    friendlyFormatter.dateFormat = "yyyy-MM-dd, HH:mm" // 可自定义格式,比如"MMM dd, yyyy hh:mm a"
    // 关键:设置时区和本地化,避免显示时间和预期不符
    friendlyFormatter.timeZone = TimeZone.current
    friendlyFormatter.locale = Locale.current
    
    return friendlyFormatter.string(from: date)
}

方法二:手动配置DateFormatter(兼容iOS 9及以下)

如果需要兼容旧系统,就手动写匹配的dateFormat:

func convertISOToFriendlyDate(dateString: String) -> String {
    let inputFormatter = DateFormatter()
    // 严格匹配输入的ISO格式:2020-03-07T12:18:26.347Z
    inputFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    inputFormatter.timeZone = TimeZone(identifier: "UTC") // 输入是UTC时间(末尾Z标识)
    inputFormatter.locale = Locale(identifier: "en_US_POSIX") // 必须设置,避免本地化干扰解析
    
    guard let date = inputFormatter.date(from: dateString) else {
        return "无效日期"
    }
    
    let outputFormatter = DateFormatter()
    outputFormatter.dateFormat = "yyyy-MM-dd, HH:mm"
    outputFormatter.timeZone = TimeZone.current
    outputFormatter.locale = Locale.current
    
    return outputFormatter.string(from: date)
}

通用的字符串与日期互转总结

字符串转日期

func stringToDate(dateString: String, inputFormat: String, timeZone: TimeZone = TimeZone(identifier: "UTC")!) -> Date? {
    let formatter = DateFormatter()
    formatter.dateFormat = inputFormat
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = timeZone
    return formatter.date(from: dateString)
}

日期转字符串

func dateToString(date: Date, outputFormat: String) -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = outputFormat
    formatter.locale = Locale.current
    formatter.timeZone = TimeZone.current
    return formatter.string(from: date)
}

必须注意的细节

  • dateFormat必须严格匹配:每个字符对应特定日期组件,比如T是固定分隔符,SSS代表毫秒,Z代表UTC时区,不能写错。
  • 强制设置en_US_POSIX本地化:解析固定格式字符串时,避免系统语言设置(比如不同语言的月份缩写)导致解析失败。
  • 时区要对应:输入的Z表示UTC时间,解析时要把时区设为UTC,输出时再转成用户当前时区,才能显示正确的本地时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:03:11