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格式的字符串,我们需要分两步走:
- 用匹配输入格式的工具把原始字符串解析成
Date类型 - 再用另一个格式化器把
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
相关产品推荐
相关产品推荐

