Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift iOS doesRelativeDateFormatting have different values besides "Today" and "Yesterday"?

I have a number of dates that I am trying to represent using a relative date such as "Today, Yesterday, 1 week ago, 1 month ago" etc...

This is the Swift code I am using:

let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateFormatter.doesRelativeDateFormatting = true
let uploadDate = dateFormatter.stringFromDate(date)

Only "Today" and "Yesterday" are represented and the rest of the dates appear like the below: Nov 24, 2014 Nov 17, 2014 etc...

Is there another way to represent all the dates using relative dating instead of the actual dates?

like image 421
Justin W. Avatar asked Dec 05 '14 07:12

Justin W.


1 Answers

edit/Update: Xcode 8.3.2 • Swift 3.1

It is really easy if you use extensions and Calendar methods to help you with your calendrical calculations:

extension Date {
    var yearsFromNow: Int {
        return Calendar.current.dateComponents([.year], from: self, to: Date()).year!
    }
    var monthsFromNow: Int {
        return Calendar.current.dateComponents([.month], from: self, to: Date()).month!
    }
    var weeksFromNow: Int {
        return Calendar.current.dateComponents([.weekOfYear], from: self, to: Date()).weekOfYear!
    }
    var daysFromNow: Int {
        return Calendar.current.dateComponents([.day], from: self, to: Date()).day!
    }
    var isInYesterday: Bool {
        return Calendar.current.isDateInYesterday(self)
    }
    var hoursFromNow: Int {
        return Calendar.current.dateComponents([.hour], from: self, to: Date()).hour!
    }
    var minutesFromNow: Int {
        return Calendar.current.dateComponents([.minute], from: self, to: Date()).minute!
    }
    var secondsFromNow: Int {
        return Calendar.current.dateComponents([.second], from: self, to: Date()).second!
    }
    var relativeTime: String {
        if yearsFromNow > 0 { return "\(yearsFromNow) year" + (yearsFromNow > 1 ? "s" : "") + " ago" }
        if monthsFromNow > 0 { return "\(monthsFromNow) month" + (monthsFromNow > 1 ? "s" : "") + " ago" }
        if weeksFromNow > 0 { return "\(weeksFromNow) week" + (weeksFromNow > 1 ? "s" : "") + " ago" }
        if isInYesterday { return "Yesterday" }
        if daysFromNow > 0 { return "\(daysFromNow) day" + (daysFromNow > 1 ? "s" : "") + " ago" }
        if hoursFromNow > 0 { return "\(hoursFromNow) hour" + (hoursFromNow > 1 ? "s" : "") + " ago" }
        if minutesFromNow > 0 { return "\(minutesFromNow) minute" + (minutesFromNow > 1 ? "s" : "") + " ago" }
        if secondsFromNow > 0 { return secondsFromNow < 15 ? "Just now"
            : "\(secondsFromNow) second" + (secondsFromNow > 1 ? "s" : "") + " ago" }
        return ""
    }
}

Testing

let calendar =  Calendar.current

let date1 = DateComponents(calendar: calendar, year: 2016, month:  3, day: 14, hour: 22, minute: 39).date!
let date2 = DateComponents(calendar: calendar, year: 2019, month:  4, day: 18, hour: 22, minute: 39).date!
let date3 = DateComponents(calendar: calendar, year: 2019, month: 6, day:  2, hour: 12, minute: 38).date!
let date4 = DateComponents(calendar: calendar, year: 2019, month: 6, day:  14, hour: 3, minute: 0).date!
let date5 = DateComponents(calendar: calendar, year: 2019, month: 6, day:  17, hour: 23, minute: 45).date!
let date6 = DateComponents(calendar: calendar, year: 2019, month: 6, day:  18, hour: 19, minute:  17).date!
let timeOffset1 = date1.relativeTime // "3 years ago"
let timeOffset2 = date2.relativeTime // "1 month ago"
let timeOffset3 = date3.relativeTime // "2 weeks ago"
let timeOffset4 = date4.relativeTime // "4 days ago"
let timeOffset5 = date5.relativeTime // "Yesterday"
let timeOffset6 = date6.relativeTime // "Just now"
like image 142
Leo Dabus Avatar answered Oct 06 '22 23:10

Leo Dabus