Swift display time ago from Date (NSDate)

Swift 5.1 (iOS 13)

Since iOS 13 you can use Apple's RelativeDateFormatter. The advantage is the resulting string is localized.

let date = Date().addingTimeInterval(-15000)

let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
let string = formatter.localizedString(for: date, relativeTo: Date())

print(string) // 4 hours ago

See for example this blog post.


If you just want a Time Ago extension for Date go to the bottom of the answer 😊

I'll show you an example just to get seconds ago and after I'll show your extension updated.

Note: you can use directly the date from Pase if you want:

if let pastDate = (object?["createdAt"] as? Date) {
    cell.TimeAgo.text = pastDate.timeAgoDisplay()
}

Since Swift 5.1

Example how to display seconds ago with Swift 5.1:

Since iOS13 Apple introduce a new class RelativeDateTimeFormatter

extension Date {
    func timeAgoDisplay() -> String {
        let formatter = RelativeDateTimeFormatter()
        formatter.unitsStyle = .full
        return formatter.localizedString(for: self, relativeTo: Date())
    }
}

This class will allow you to get a time ago string based on your language. It automatically select the right unit of time based on your interval, here is an example:

|--------------------------|------------------|
| Time interval in seconds |      Display     |
|--------------------------|------------------|
|             -6           |   6 seconds ago  |
|            -60           |   1 minute ago   |
|           -600           |  10 minutes ago  |
|          -6000           |    1 hour ago    |
|         -60000           |   16 hours ago   |
|--------------------------|------------------|

You'll notice that it handle automatically plurals for you.

Swift 3 or Swift 4

Example how to get seconds ago with Swift 3 or Swift 4:

First: To get the number of seconds ago we need to check if we have one minutes or less, to get the current Date minus one minute you can write that:

let minuteAgo = calendar.date(byAdding: .minute, value: -1, to: Date())!

Second: Now compare the 2 dates! (In the case of your extension we replace yourDate by self) and get the difference between this 2 dates.

if (minuteAgo < yourDate) {
    let diff = Calendar.current.dateComponents([.second], from: yourDate, to: Date()).second ?? 0
    print("\(diff) sec ago")
}

That's all, now you can print the time ago !

So your extension is like this: (This is a simple extension to get the time ago)

extension Date {
    func timeAgoDisplay() -> String {
 
        let calendar = Calendar.current
        let minuteAgo = calendar.date(byAdding: .minute, value: -1, to: Date())!
        let hourAgo = calendar.date(byAdding: .hour, value: -1, to: Date())!
        let dayAgo = calendar.date(byAdding: .day, value: -1, to: Date())!
        let weekAgo = calendar.date(byAdding: .day, value: -7, to: Date())!

        if minuteAgo < self {
            let diff = Calendar.current.dateComponents([.second], from: self, to: Date()).second ?? 0
            return "\(diff) sec ago"
        } else if hourAgo < self {
            let diff = Calendar.current.dateComponents([.minute], from: self, to: Date()).minute ?? 0
            return "\(diff) min ago"
        } else if dayAgo < self {
            let diff = Calendar.current.dateComponents([.hour], from: self, to: Date()).hour ?? 0
            return "\(diff) hrs ago"
        } else if weekAgo < self {
            let diff = Calendar.current.dateComponents([.day], from: self, to: Date()).day ?? 0
            return "\(diff) days ago"
        }
        let diff = Calendar.current.dateComponents([.weekOfYear], from: self, to: Date()).weekOfYear ?? 0
        return "\(diff) weeks ago"
    }
}

To use it, this is very straightforward:

var now = Date()
now.timeAgoDisplay()