Reputation: 67
When a user clicks on a post from the feed, I want to display the time that each comment was posted. I am trying to convert the Date().timeIntervalSince1970 value to "x time ago" for when it was posted.
Before view loads, I am declaring a now variable for the date today.
let now = Date()
The date is assigned when I set up the dictionary for the comments like.
let commentValues: [String: Any] = [
"comment" : comment,
"uid": uid,
"commentDate": Date().timeIntervalSince1970
]
I am fetching the comments like this where I also call the date function and assign it to the date label in storyboard.
var comments = [Comment]()
fileprivate func fetchComments() {
guard let postID = self.post?.id else {return}
let commentRef = Database.database().reference().child("comments").child(postID)
commentRef.observe(.childAdded, with: { (snapshot) in
guard let dict = snapshot.value as? [String: Any] else {return}
guard let comment = dict["comment"] as? String else {return}
guard let uid = dict["uid"] as? String else {return}
guard let commentDate = dict["commentDate"] as? Double else {return}
let userRef = Database.database().reference().child("users/\(String(describing: uid))/profile")
userRef.observe(.value, with: { snapshot in
guard let value = snapshot.value as? [String:Any] else {return}
let username = value["username"]
let uid = dict["uid"]
let email = value["email"]
let myTimeInterval = TimeInterval(commentDate)
let time = Date(timeIntervalSinceNow: myTimeInterval)
let userProfile = User(uid: uid as! String, username: username as! String, email: email as! String)
let comment = Comment(uid: uid as! String, user: userProfile, comment: comment, time: time.timeAgoDisplay())
self.comments.append(comment)
self.commentCollectionView.reloadData()
})
})
}
I have set up a date extension where I am trying to calculate the timeAgo for the 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
let year = 12 * month
if secondsAgo < minute {
print("\(secondsAgo)s ago")
return "\(secondsAgo)s ago"
} else if secondsAgo < hour {
return "\(secondsAgo)m ago"
} else if secondsAgo < day {
return "\(secondsAgo)hr ago"
} else if secondsAgo < week {
return "\(secondsAgo)d ago"
} else if secondsAgo < month {
return "\(secondsAgo)w ago"
} else if secondsAgo < year {
return "\(secondsAgo)mo ago"
}
return "\(secondsAgo)yr ago"
}
}
The date is being displayed but I'm getting the result as "-12983918s ago". How do I display the time as "2s ago" or "1h ago" or "1w ago" etc?
Upvotes: 4
Views: 777
Reputation: 576
Here is an example using Calendar.component to differentiate the possible time outcomes.
if let timestamp = post?.timestamp {
print(timestamp)
let timestampDate = Date(timeIntervalSince1970: Double(timestamp))
let now = Date()
let components = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfMonth])
let diff = Calendar.current.dateComponents(components, from: timestampDate, to: now)
var timeText = ""
if diff.second! <= 0 {
timeText = "Now"
}
if diff.second! > 0 && diff.minute! == 0 {
timeText = (diff.second == 1) ? "\(diff.second!) second ago" : "\(diff.second!) seconds ago"
}
if diff.minute! > 0 && diff.hour! == 0 {
timeText = (diff.minute == 1) ? "\(diff.minute!) minute ago" : "\(diff.minute!) minutes ago"
}
if diff.hour! > 0 && diff.day! == 0 {
timeText = (diff.hour == 1) ? "\(diff.hour!) hour ago" : "\(diff.hour!) hours ago"
}
if diff.day! > 0 && diff.weekOfMonth! == 0 {
timeText = (diff.day == 1) ? "\(diff.day!) day ago" : "\(diff.day!) days ago"
}
if diff.weekOfMonth! > 0 {
timeText = (diff.weekOfMonth == 1) ? "\(diff.weekOfMonth!) week ago" : "\(diff.weekOfMonth!) weeks ago"
}
timeLabel.text = timeText
}
This example appends the timestamp of a 'post'...but you could use the same logic for your comments. Give it a go and let me know if you have any questions. Cheers!
Edit: Including documentation on Calendar.component https://developer.apple.com/documentation/foundation/calendar.component
Upvotes: 2
Reputation: 1662
You need convert the secondsAgo
to second, date, month, year,...:
Here's an idea for that :
func timeAgoDisplay() -> String {
let secondsAgo = Int(Date().timeIntervalSince(self))
var result = ""
if secondsAgo >= 60 {
let minutesAgo = secondsAgo / 60
if minutesAgo >= 60 {
let hoursAgo = minutesAgo / 60
if hoursAgo >= 60 {
let daysAgo = hoursAgo / 24
if daysAgo >= 30 {
let monthsAgo = daysAgo / 12
if monthsAgo >= 12 {
let yearsAgo = monthsAgo / 12
result = "\(yearsAgo)y ago"
} else { // months < 12
result = "\(monthsAgo)mo ago"
}
} else { // days < 30
result = "\(daysAgo)d ago"
}
} else { // hours < 24
result = "\(hoursAgo)h ago"
}
} else { // minutes < 60ms
result = "\(minutesAgo)m ago"
}
} else { // seconds < 60s
result = "\(secondsAgo)seconds ago"
}
return result
}
Hope this helpful
Upvotes: 0