Firebase时间戳转「多久前」格式异常问题求助
你的代码里出现负数时间(比如-12983918s ago),以及时间格式计算错误(比如应该显示2m ago却显示120m ago),主要是两个关键地方出错了,咱们一步步来修正:
1. 评论日期对象初始化错误
你存储的commentDate是Date().timeIntervalSince1970——这是从1970年到评论发布时刻的总秒数(一个正数)。但你在获取时用了错误的Date初始化方法:
// 错误代码 let time = Date(timeIntervalSinceNow: myTimeInterval)
Date(timeIntervalSinceNow:)的参数是相对于当前时间的偏移量:正数表示当前时间之后的日期,负数表示当前时间之前的日期。而你的myTimeInterval是一个很大的正数(比如1700000000),这会创建一个远在未来的日期,导致后续计算Date().timeIntervalSince(self)时,得到的是「当前时间 - 未来时间」,结果自然是负数。
修正方法:
用Date(timeIntervalSince1970:)来创建评论的日期对象,这个方法专门用来把1970时间戳转换成对应的Date:
let myTimeInterval = TimeInterval(commentDate) let commentDateObj = Date(timeIntervalSince1970: myTimeInterval) // 正确初始化
然后在创建Comment时,调用这个对象的timeAgoDisplay():
let comment = Comment(uid: uid as! String, user: userProfile, comment: comment, time: commentDateObj.timeAgoDisplay())
2. Date扩展的时间计算逻辑错误
你的timeAgoDisplay()方法里,直接返回了secondsAgo的原始值,比如120秒会显示120m ago,而不是正确的2m ago。你需要把总秒数转换成对应的单位(分钟、小时等)的数量。
修正后的Date扩展:
extension Date { func timeAgoDisplay() -> String { let secondsAgo = Int(Date().timeIntervalSince(self)) let minute = 60 let hour = 60 * minute let day = 24 * hour let week = 7 * day let month = 4 * week // 这里是简化计算,若需要更精准的月份可以用Calendar API let year = 12 * month switch secondsAgo { case 0..<minute: return "\(secondsAgo)s ago" case minute..<hour: let minutes = secondsAgo / minute return "\(minutes)m ago" case hour..<day: let hours = secondsAgo / hour return "\(hours)hr ago" case day..<week: let days = secondsAgo / day return "\(days)d ago" case week..<month: let weeks = secondsAgo / week return "\(weeks)w ago" case month..<year: let months = secondsAgo / month return "\(months)mo ago" default: let years = secondsAgo / year return "\(years)yr ago" } } }
额外优化建议
在fetchComments()里,你对userRef用了.observe(.value),这会监听用户数据的所有变化,每次用户信息更新时都会重新触发评论加载,可能导致重复添加评论或性能问题。建议改成.observeSingleEvent(of: .value),只获取一次用户信息:
userRef.observeSingleEvent(of: .value, with: { snapshot in // 原有的用户信息解析逻辑 })
这样修改后,你的评论时间应该就能正确显示为2s ago、1h ago这类格式了。
内容的提问来源于stack exchange,提问作者Dipali Bajaj

