Getting the difference between two Dates (months/days/hours/minutes/seconds) in Swift

前端 未结 19 2030
时光说笑
时光说笑 2020-11-22 02:16

I am trying to get the difference between the current date as NSDate() and a date from a PHP time(); call for example: NSDate(timeIntervalSin

相关标签:
19条回答
  • 2020-11-22 02:46

    Xcode 8.3 • Swift 3.1 or later

    You can use Calendar to help you create an extension to do your date calculations as follow:

    extension Date {
        /// Returns the amount of years from another date
        func years(from date: Date) -> Int {
            return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
        }
        /// Returns the amount of months from another date
        func months(from date: Date) -> Int {
            return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
        }
        /// Returns the amount of weeks from another date
        func weeks(from date: Date) -> Int {
            return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
        }
        /// Returns the amount of days from another date
        func days(from date: Date) -> Int {
            return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
        }
        /// Returns the amount of hours from another date
        func hours(from date: Date) -> Int {
            return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
        }
        /// Returns the amount of minutes from another date
        func minutes(from date: Date) -> Int {
            return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
        }
        /// Returns the amount of seconds from another date
        func seconds(from date: Date) -> Int {
            return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
        }
        /// Returns the a custom time interval description from another date
        func offset(from date: Date) -> String {
            if years(from: date)   > 0 { return "\(years(from: date))y"   }
            if months(from: date)  > 0 { return "\(months(from: date))M"  }
            if weeks(from: date)   > 0 { return "\(weeks(from: date))w"   }
            if days(from: date)    > 0 { return "\(days(from: date))d"    }
            if hours(from: date)   > 0 { return "\(hours(from: date))h"   }
            if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
            if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
            return ""
        }
    }
    

    Using Date Components Formatter

    let dateComponentsFormatter = DateComponentsFormatter()
    dateComponentsFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth, .month, .second]
    dateComponentsFormatter.maximumUnitCount = 1
    dateComponentsFormatter.unitsStyle = .full
    dateComponentsFormatter.string(from: Date(), to: Date(timeIntervalSinceNow: 4000000))  // "1 month"
    

    let date1 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
    let date2 = DateComponents(calendar: .current, year: 2015, month: 8, day: 28, hour: 5, minute: 9).date!
    
    let years = date2.years(from: date1)     // 0
    let months = date2.months(from: date1)   // 9
    let weeks = date2.weeks(from: date1)     // 39
    let days = date2.days(from: date1)       // 273
    let hours = date2.hours(from: date1)     // 6,553
    let minutes = date2.minutes(from: date1) // 393,180
    let seconds = date2.seconds(from: date1) // 23,590,800
    
    let timeOffset = date2.offset(from: date1) // "9M"
    
    let date3 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
    let date4 = DateComponents(calendar: .current, year: 2015, month: 11, day: 28, hour: 5, minute: 9).date!
    
    let timeOffset2 = date4.offset(from: date3) // "1y"
    
    let date5 = DateComponents(calendar: .current, year: 2017, month: 4, day: 28).date!
    let now = Date()
    let timeOffset3 = now.offset(from: date5) // "1w"
    
    0 讨论(0)
  • 2020-11-22 02:46

    Use this code:

    let registrationDateString = "2008-10-06 00:00:00"
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
        if let registrationDate = dateFormatter.date(from: registrationDateString) {
            let currentDate = Date()
            let dateDifference = Calendar.current.dateComponents([.day, .month, .year],
                                                                   from: registrationDate,
                                                                   to: currentDate)
            print("--------------------- Result: \(dateDifference.year ?? 0) years \(dateDifference.month ?? 0) months and \(dateDifference.day ?? 0) days")
        } else {
            print("--------------------- No result")
        }
    

    Output is: Result: 10 years 1 months and 18 days

    0 讨论(0)
  • 2020-11-22 02:47

    --> Use this to find time gap between two dates in Swift(With two Strings).

    func timeGapBetweenDates(previousDate : String,currentDate : String)
    {
        let dateString1 = previousDate
        let dateString2 = currentDate
    
        let Dateformatter = DateFormatter()
        Dateformatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    
    
        let date1 = Dateformatter.date(from: dateString1)
        let date2 = Dateformatter.date(from: dateString2)
    
    
        let distanceBetweenDates: TimeInterval? = date2?.timeIntervalSince(date1!)
        let secondsInAnHour: Double = 3600
        let minsInAnHour: Double = 60
        let secondsInDays: Double = 86400
        let secondsInWeek: Double = 604800
        let secondsInMonths : Double = 2592000
        let secondsInYears : Double = 31104000
    
        let minBetweenDates = Int((distanceBetweenDates! / minsInAnHour))
        let hoursBetweenDates = Int((distanceBetweenDates! / secondsInAnHour))
        let daysBetweenDates = Int((distanceBetweenDates! / secondsInDays))
        let weekBetweenDates = Int((distanceBetweenDates! / secondsInWeek))
        let monthsbetweenDates = Int((distanceBetweenDates! / secondsInMonths))
        let yearbetweenDates = Int((distanceBetweenDates! / secondsInYears))
        let secbetweenDates = Int(distanceBetweenDates!)
    
    
    
    
        if yearbetweenDates > 0
        {
            print(yearbetweenDates,"years")//0 years
        }
        else if monthsbetweenDates > 0
        {
            print(monthsbetweenDates,"months")//0 months
        }
        else if weekBetweenDates > 0
        {
            print(weekBetweenDates,"weeks")//0 weeks
        }
        else if daysBetweenDates > 0
        {
            print(daysBetweenDates,"days")//5 days
        }
        else if hoursBetweenDates > 0
        {
            print(hoursBetweenDates,"hours")//120 hours
        }
        else if minBetweenDates > 0
        {
            print(minBetweenDates,"minutes")//7200 minutes
        }
        else if secbetweenDates > 0
        {
            print(secbetweenDates,"seconds")//seconds
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:47

    Some addition in jose920405 answer to make it compatible with Swift 3.0 and above

    func getDateTimeDiff(dateStr:String) -> String {
        
        let formatter : DateFormatter = DateFormatter()
        formatter.timeZone = NSTimeZone.local
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        let now = formatter.string(from: NSDate() as Date)
        let startDate = formatter.date(from: dateStr)
        let endDate = formatter.date(from: now)
        
        // *** create calendar object ***
        var calendar = NSCalendar.current
        
        // *** Get components using current Local & Timezone ***
        print(calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: startDate!))
        
        // *** define calendar components to use as well Timezone to UTC ***
        let unitFlags = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
        calendar.timeZone = TimeZone(identifier: "UTC")!
        let dateComponents = calendar.dateComponents(unitFlags, from: startDate!, to: endDate!)
        
        // *** Get Individual components from date ***
        let years = dateComponents.year!
        let months = dateComponents.month!
        let days = dateComponents.day!
        let hours = dateComponents.hour!
        let minutes = dateComponents.minute!
        let seconds = dateComponents.second!
        
        var timeAgo = ""
        
        if (seconds > 0){
            if seconds < 2 {
                timeAgo = "Second Ago"
            }
            else{
                timeAgo = "\(seconds) Second Ago"
            }
        }
        
        if (minutes > 0){
            if minutes < 2 {
                timeAgo = "Minute Ago"
            }
            else{
                timeAgo = "\(minutes) Minutes Ago"
            }
        }
        
        if(hours > 0){
            if hours < 2 {
                timeAgo = "Hour Ago"
            }
            else{
                timeAgo = "\(hours) Hours Ago"
            }
        }
        
        if (days > 0) {
            if days < 2 {
                timeAgo = "Day Ago"
            }
            else{
                timeAgo = "\(days) Days Ago"
            }
        }
        
        if(months > 0){
            if months < 2 {
                timeAgo = "Month Ago"
            }
            else{
                timeAgo = "\(months) Months Ago"
            }
        }
        
        if(years > 0){
            if years < 2 {
                timeAgo = "Year Ago"
            }
            else{
                timeAgo = "\(years) Years Ago"
            }
        }
        
        DLog("timeAgo is ===> \(timeAgo)")
        return timeAgo;
    }
    
    0 讨论(0)
  • 2020-11-22 02:49

    You ask:

    I'd like to have a function that compares the two dates and if(seconds > 60) then it returns minutes, if(minutes > 60) return hours and if(hours > 24) return days and so on.

    I'm assuming that you're trying to build a string representation of the elapsed time between two dates. Rather than writing your own code to do that, Apple already has a class designed to do precisely that. Namely, use DateComponentsFormatter, set allowedUnits to whatever values make sense to your app, set unitsStyle to whatever you want (e.g. .full), and then call string(from:to:).

    E.g. in Swift 3:

    let previousDate = ...
    let now = Date()
    
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full
    formatter.allowedUnits = [.month, .day, .hour, .minute, .second]
    formatter.maximumUnitCount = 2   // often, you don't care about seconds if the elapsed time is in months, so you'll set max unit to whatever is appropriate in your case
    
    let string = formatter.string(from: previousDate, to: now)
    

    This also will localize the string appropriate for the device in question.

    Or, in Swift 2.3:

    let previousDate = ...
    let now = NSDate()
    
    let formatter = NSDateComponentsFormatter()
    formatter.unitsStyle = .Full
    formatter.allowedUnits = [.Month, .Day, .Hour, .Minute, .Second]
    formatter.maximumUnitCount = 2
    
    let string = formatter.stringFromDate(previousDate, toDate: now)
    

    If you're looking for the actual numeric values, just use dateComponents. E.g. in Swift 3:

    let components = Calendar.current.dateComponents([.month, .day, .hour, .minute, .second], from: previousDate, to: now)
    

    Or, in Swift 2.3:

    let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: [])
    
    0 讨论(0)
  • 2020-11-22 02:51

    For XCode Version 8.3.3 & Swift 3.0:

        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .short
    
        var beginDate = "2017-08-24 12:00:00"
        var endDate = "2017-09-07 12:00:00"
    
    
        let startDateTime = dateFormatter.date(from: beginDate) //according to date format your date string
        print(startDateTime ?? "") //Convert String to Date
    
        let endDateTime = dateFormatter.date(from: endDate) //according to date format your date string
        print(endDateTime ?? "") //Convert String to Date
    
        let dateComponentsFormatter = DateComponentsFormatter()
        dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.minute,NSCalendar.Unit.hour,NSCalendar.Unit.day]
    
    
       let interval = endDateTime!.timeIntervalSince(startDateTime!)
       var diff = dateComponentsFormatter.string(from: interval)!
    
       print(diff)
    
       var day_i  = 0
       var hour_i = 0
       var min_i = 0
    
    
         if (diff.contains("d"))
           {
                  let day = diff.substring(to: (diff.range(of: "d")?.lowerBound)!)
    
                   day_i  = Int(day)!
                   print ("day --> \(day_i)")
    
                   diff = diff.substring(from:(diff.range(of : " ")?.upperBound )!)
                   print(diff)
           }
    
    
           let hour = diff.substring(to: (diff.range(of : ":")?.lowerBound )!)
           hour_i  = Int(hour)!
           print ("hour --> \(hour_i)")
    
           let min = diff.substring(from: (diff.range(of : ":")?.upperBound )!)
           min_i  = Int(min)!
           print ("min --> \(min_i)")
    
    0 讨论(0)
提交回复
热议问题