iOS开发:实现社交平台式相对时间显示遇返回"in 0 seconds"异常
解决RelativeDateTimeFormatter返回"in 0 seconds"的问题
问题根源
你的代码返回"in 0 seconds",核心原因是dateFormatter.date(from: dateStr!)转换失败,导致exampleDate fallback到当前时间Date(),和对比的relativeTo: Date()时间差为0秒。主要诱因有两个:
dateStr无效:直接从cell.dateLbl.text取日期字符串,但初始状态下该label文本可能并非API返回的"2022-12-03 05:24:00"格式内容,导致转换失败。- 时区不匹配:API返回的日期通常为UTC时区,但
DateFormatter默认使用设备本地时区,转换时会把UTC日期误当成本地时间处理,最终得到的日期与当前时间偏差异常(极端情况会刚好等于当前时间)。
解决方案
1. 从数据源获取正确的日期字符串
不要依赖UI控件的文本,直接从API返回的模型对象中获取原始created_at值:
// 假设你的数据源模型是Post,包含createdAt属性 let post = dataSource[indexPath.row] let dateStr = post.createdAt // 直接取API返回的原始日期字符串
2. 配置DateFormatter的时区与安全转换
给DateFormatter指定UTC时区(匹配API返回时区),同时用可选绑定避免强制解包的风险:
let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" dateFormatter.timeZone = TimeZone(identifier: "UTC") // 关键:设置时区为UTC guard let exampleDate = dateFormatter.date(from: dateStr) else { // 转换失败时的降级处理,比如显示原始日期 cell.dateLbl.text = dateStr return }
3. 调整RelativeDateTimeFormatter的样式
如果需要"1小时前""4天前"这类简洁格式,将unitsStyle设置为.short或.abbreviated:
let formatter = RelativeDateTimeFormatter() formatter.unitsStyle = .short // 生成简洁的相对日期文本 let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date()) cell.dateLbl.text = relativeDate
完整修正代码
// 从数据源获取正确的日期字符串 let post = dataSource[indexPath.row] let dateStr = post.createdAt let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" dateFormatter.timeZone = TimeZone(identifier: "UTC") guard let exampleDate = dateFormatter.date(from: dateStr) else { cell.dateLbl.text = dateStr return } let formatter = RelativeDateTimeFormatter() formatter.unitsStyle = .short let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date()) cell.dateLbl.text = relativeDate
内容的提问来源于stack exchange,提问作者Abhinandan Pratap
相关产品推荐
相关产品推荐

