Q:

Swift 3 - How to display time as String (each 5 minutes)

I am having some issue trying to display time with good format and logic as a String in Swift 3.
Context
Our users can send us informations to our server. I am displaying those informations in the App, and doing some statistics about it.
For example I want to calculate and display the elapsed time since the first information is posted.
I have the oldest user information (as timestamp) and I want to display the elapsed time.
For example if the elapsed time (from now since the first information posted) is from 0 to 5 minutes.
"X informations posted in the last 5 minutes" -> [0-5] minutes
"X informations posted in the last 10 minutes" -> ]5-10] minutes
"X informations posted in the last hour" -> 1h and more
How can I handle this specific cases and which solution enables me to do this in swift.
This is what I have done so far :
self.info is my Information array (each information has a timestamp property
private func getInformationTime() -> String {

        //Get the oldest Information
        let sortedArray = self.info.sorted(by: { $0.timestamp < $1.timestamp })
        let oldestInfoDate = Date(timeIntervalSince1970: (sortedArray.first?.timestamp)!)
        let now = Date()

        let formatter = DateComponentsFormatter()
        formatter.unitsStyle = .short
        formatter.allowedUnits = [.minute]
        formatter.maximumUnitCount = 1

        let string = formatter.string(from: oldestInfoDate as Date, to: now as Date)

        return string!
    }

I call it this way and it display me this :
let infoTime = self. getInformationTime()          
let message = "\(self.info.count) informations in \(infoTime)"        
print(message)

Result:  244 informations in 184 min
The result is the appropriate one, I have the good number and the good time value.
I want to be able to properly format it.
PS: My app use internationalization so that I have to be able to translate it in different languages (String file).

A:

here is an extension which can help you out.
extension Date {
func years(from date: Date) -> Int {
    return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
func months(from date: Date) -> Int {
    return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
func weeks(from date: Date) -> Int {
    return Calendar.current.dateComponents([.weekOfYear], from: date, to: self).weekOfYear ?? 0
}
func days(from date: Date) -> Int {
    return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
func hours(from date: Date) -> Int {
    return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
func minutes(from date: Date) -> Int {
    return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
func seconds(from date: Date) -> Int {
    return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}

var relativeTime: String {
    let now = Date()
    if now.years(from: self)   > 0 {
        return now.years(from: self).description  + " year"  + { return now.years(from: self)   > 1 ? "s" : "" }() + " ago"
    }
    if now.months(from: self)  > 0 {
        return now.months(from: self).description + " month" + { return now.months(from: self)  > 1 ? "s" : "" }() + " ago"
    }
    if now.weeks(from:self)   > 0 {
        return now.weeks(from: self).description  + " week"  + { return now.weeks(from: self)   > 1 ? "s" : "" }() + " ago"
    }
    if now.days(from: self)    > 0 {
        if now.days(from:self) == 1 { return "Yesterday" }
        return now.days(from: self).description + " days ago"
    }
    if now.hours(from: self)   > 0 {
        return "\(now.hours(from: self)) hour"     + { return now.hours(from: self)   > 1 ? "s" : "" }() + " ago"
    }
    if now.minutes(from: self) > 0 {
        return "\(now.minutes(from: self)) minute" + { return now.minutes(from: self) > 1 ? "s" : "" }() + " ago"
    }
    if now.seconds(from: self) > 0 {
        if now.seconds(from: self) < 15 { return "Just now"  }
        return "\(now.seconds(from: self)) second" + { return now.seconds(from: self) > 1 ? "s" : "" }() + " ago"
    }
    return ""
}
}

you can use it like this
let timePeriod = (oldestInfoDate as Date).relativeTime

If you need any help understanding it, do let me know.

