Swift convert time to time ago

前端 未结 13 1205
一个人的身影
一个人的身影 2020-12-24 02:14

In Swift5, we have RelativeDateTimeFormatter

Prior to Swift5:


I\'m trying to convert time to time ago, what i wanna do is:

from 1

相关标签:
13条回答
  • 2020-12-24 02:45

    Similar to the accepted answer with cleaner String processing:

    extension Date
    {
        func getElapsedInterval() -> String
        {
            let interval = Calendar.current.dateComponents([.year, .month, .day], from: self, to: Date())
            
            if let yearsPassed = interval.year,
                yearsPassed > 0
            {
                return "\(yearsPassed) year\(yearsPassed == 1 ? "" : "s") ago"
            }
            else if let monthsPassed = interval.month,
                monthsPassed > 0
            {
                return "\(monthsPassed) month\(monthsPassed == 1 ? "" : "s") ago"
            }
            else if let daysPassed = interval.day,
                daysPassed > 0
            {
                return "\(daysPassed) day\(daysPassed == 1 ? "" : "s") ago"
            }
            
            return "a moment ago"
        }
    }
    
    0 讨论(0)
  • 2020-12-24 02:50

    I'll just update the Truongky's answer for Swif 3:

    extension Date {
    
    func getElapsedInterval() -> String {
    
        let interval = Calendar.current.dateComponents([.year, .month, .day], from: self, to: Date())
    
        if let year = interval.year, year > 0 {
            return year == 1 ? "\(year)" + " " + "year ago" :
                "\(year)" + " " + "years ago"
        } else if let month = interval.month, month > 0 {
            return month == 1 ? "\(month)" + " " + "month ago" :
                "\(month)" + " " + "months ago"
        } else if let day = interval.day, day > 0 {
            return day == 1 ? "\(day)" + " " + "day ago" :
                "\(day)" + " " + "days ago"
        } else {
            return "a moment ago"
    
        }
    
    }
    }
    

    If you prefer a localizable response instead of only english this code will do the work

    extension Date {
    func getElapsedInterval() -> String {
    
        var calendar = Calendar.current
        calendar.locale = Locale(identifier: Bundle.main.preferredLocalizations[0]) 
    // IF THE USER HAVE THE PHONE IN SPANISH BUT YOUR APP ONLY SUPPORTS I.E. ENGLISH AND GERMAN
    // WE SHOULD CHANGE THE LOCALE OF THE FORMATTER TO THE PREFERRED ONE 
    // (IS THE LOCALE THAT THE USER IS SEEING THE APP), IF NOT, THIS ELAPSED TIME 
    // IS GOING TO APPEAR IN SPANISH
    
        let formatter = DateComponentsFormatter()
        formatter.unitsStyle = .full
        formatter.maximumUnitCount = 1
        formatter.calendar = calendar
    
        var dateString: String?
    
        let interval = calendar.dateComponents([.year, .month, .weekOfYear, .day], from: self, to: Date())
    
        if let year = interval.year, year > 0 {
            formatter.allowedUnits = [.year] //2 years
        } else if let month = interval.month, month > 0 {
            formatter.allowedUnits = [.month] //1 month
        } else if let week = interval.weekOfYear, week > 0 {
            formatter.allowedUnits = [.weekOfMonth] //3 weeks
        } else if let day = interval.day, day > 0 {
            formatter.allowedUnits = [.day] // 6 days
        } else {
            let dateFormatter = DateFormatter()
            dateFormatter.locale = Locale(identifier: Bundle.main.preferredLocalizations[0]) //--> IF THE USER HAVE THE PHONE IN SPANISH BUT YOUR APP ONLY SUPPORTS I.E. ENGLISH AND GERMAN WE SHOULD CHANGE THE LOCALE OF THE FORMATTER TO THE PREFERRED ONE (IS THE LOCALE THAT THE USER IS SEEING THE APP), IF NOT, THIS ELAPSED TIME IS GOING TO APPEAR IN SPANISH
            dateFormatter.dateStyle = .medium
            dateFormatter.doesRelativeDateFormatting = true
    
            dateString = dateFormatter.string(from: self) // IS GOING TO SHOW 'TODAY'
        }
    
        if dateString == nil {
            dateString = formatter.string(from: self, to: Date())
        }
    
        return dateString!
    }
    
    0 讨论(0)
  • 2020-12-24 02:50

    Swift 3 version of truongky's code:

    extension Date {
    
        var timeAgoSinceNow: String {
            return getTimeAgoSinceNow()
        }
    
        private func getTimeAgoSinceNow() -> String {
    
            var interval = Calendar.current.dateComponents([.year], from: self, to: Date()).year!
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " year" : "\(interval)" + " years"
            }
    
            interval = Calendar.current.dateComponents([.month], from: self, to: Date()).month!
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " month" : "\(interval)" + " months"
            }
    
            interval = Calendar.current.dateComponents([.day], from: self, to: Date()).day!
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " day" : "\(interval)" + " days"
            }
    
            interval = Calendar.current.dateComponents([.hour], from: self, to: Date()).hour!
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " hour" : "\(interval)" + " hours"
            }
    
            interval = Calendar.current.dateComponents([.minute], from: self, to: Date()).minute!
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " minute" : "\(interval)" + " minutes"
            }
    
            return "a moment ago"
        }
    }
    
    0 讨论(0)
  • 2020-12-24 02:51

    Change your text as you want.

    extension NSDate {
    
        func getElapsedInterval() -> String {
    
            var interval = NSCalendar.currentCalendar().components(.Year, fromDate: self, toDate: NSDate(), options: []).year
    
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " " + "year" :
                "\(interval)" + " " + "years"
            }
    
            interval = NSCalendar.currentCalendar().components(.Month, fromDate: self, toDate: NSDate(), options: []).month
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " " + "month" :
                "\(interval)" + " " + "months"
            }
    
            interval = NSCalendar.currentCalendar().components(.Day, fromDate: self, toDate: NSDate(), options: []).day
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " " + "day" :
                "\(interval)" + " " + "days"
            }
    
            interval = NSCalendar.currentCalendar().components(.Hour, fromDate: self, toDate: NSDate(), options: []).hour
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " " + "hour" :
                "\(interval)" + " " + "hours"
            }
    
            interval = NSCalendar.currentCalendar().components(.Minute, fromDate: self, toDate: NSDate(), options: []).minute
            if interval > 0 {
                return interval == 1 ? "\(interval)" + " " + "minute" :
                "\(interval)" + " " + "minutes"
            }
    
            return "a moment ago"
        }
    }
    
    0 讨论(0)
  • 2020-12-24 02:53

    Using Date instead of NSDate: Answer taking from:

    func timeAgoSinceDate(_ date:Date, numericDates:Bool = false) -> String {
        let calendar = NSCalendar.current
        let unitFlags: Set<Calendar.Component> = [.minute, .hour, .day, .weekOfYear, .month, .year, .second]
        let now = Date()
        let earliest = now < date ? now : date
        let latest = (earliest == now) ? date : now
        let components = calendar.dateComponents(unitFlags, from: earliest,  to: latest)
    
        if (components.year! >= 2) {
            return "\(components.year!) years ago"
        } else if (components.year! >= 1){
            if (numericDates){
                return "1 year ago"
            } else {
                return "Last year"
            }
        } else if (components.month! >= 2) {
            return "\(components.month!) months ago"
        } else if (components.month! >= 1){
            if (numericDates){
                return "1 month ago"
            } else {
                return "Last month"
            }
        } else if (components.weekOfYear! >= 2) {
            return "\(components.weekOfYear!) weeks ago"
        } else if (components.weekOfYear! >= 1){
            if (numericDates){
                return "1 week ago"
            } else {
                return "Last week"
            }
        } else if (components.day! >= 2) {
            return "\(components.day!) days ago"
        } else if (components.day! >= 1){
            if (numericDates){
                return "1 day ago"
            } else {
                return "Yesterday"
            }
        } else if (components.hour! >= 2) {
            return "\(components.hour!) hours ago"
        } else if (components.hour! >= 1){
            if (numericDates){
                return "1 hour ago"
            } else {
                return "An hour ago"
            }
        } else if (components.minute! >= 2) {
            return "\(components.minute!) minutes ago"
        } else if (components.minute! >= 1){
            if (numericDates){
                return "1 minute ago"
            } else {
                return "A minute ago"
            }
        } else if (components.second! >= 3) {
            return "\(components.second!) seconds ago"
        } else {
            return "Just now"
        }
    
    }
    

    How to use

    var createdDate : String = "123232323" //time stamp
    var createdDataDisplayString: String {
        let date = Date(timeIntervalSince1970: Double(self.createdDate)!).timeAgoSinceDate(numericDates: true)
        return "\(date)"
    }
    print(self.createdDataDisplayString)
    
    0 讨论(0)
  • 2020-12-24 02:53

    Here is a solution you can copy paste

     func timeAgoSinceDate(_ date:Date, numericDates:Bool = false) -> String? {
        let calendar = NSCalendar.current
        let unitFlags: Set<Calendar.Component> = [.minute, .hour, .day, .weekOfYear, .month, .year, .second]
        let now = Date()
        let earliest = now < date ? now : date
        let latest = (earliest == now) ? date : now
        let components = calendar.dateComponents(unitFlags, from: earliest,  to: latest)
    
        if (components.year! >= 2) {
            return "\(components.year!)yr"
        } else if (components.year! >= 1){
            if (numericDates){
                return "1yr"
            } else {
                return "Last year"
            }
        } else if (components.month! >= 2) {
            return "\(components.month!)mo"
        } else if (components.month! >= 1){
            if (numericDates){
                return "1 mo"
            } else {
                return "Last mo"
            }
        } else if (components.weekOfYear! >= 2) {
            return "\(components.weekOfYear!) weeks"
        } else if (components.weekOfYear! >= 1){
            if (numericDates){
                return "1 week"
            } else {
                return "Last week"
            }
        } else if (components.day! >= 2) {
            return "\(components.day!) d"
        } else if (components.day! >= 1){
            if (numericDates){
                return "1 d"
            } else {
                return "1 d"
            }
        } else if (components.hour! >= 2) {
            return "\(components.hour!) hrs"
        } else if (components.hour! >= 1){
            if (numericDates){
                return "1 hr"
            } else {
                return "1 hr"
            }
        } else if (components.minute! >= 2) {
            return "\(components.minute!) m"
        } else if (components.minute! >= 1){
            if (numericDates){
                return "1 m"
            } else {
                return "2 m"
            }
        } else if (components.second! >= 3) {
            return "\(components.second!)s"
        } else {
            return "now"
        }
    
    }
    

    to call, simply use

        // the date you are getting information about 
    let dateToReference = Date()
                if let timeAgo = timeAgoSinceDate(dateToReference) {
                    //will be a String value
                    print(timeAgo)
    
                } else {
                    //just in case something goes wrong
                    print("recently")
    
                }
    
    0 讨论(0)
提交回复
热议问题