Obteniendo la diferencia entre dos NSDates en (meses / días / horas / minutos / segundos)

Estoy tratando de obtener la diferencia entre la fecha actual como NSDate() y una fecha de un PHP time(); llamar por ejemplo: NSDate(timeIntervalSinceReferenceDate: 1417147270) . ¿Cómo hago para obtener la diferencia de tiempo entre las dos fechas? Me gustaría tener una función que compare las dos fechas y if(seconds > 60) luego devuelve minutos, if(minutes > 60) devuelve horas y if(hours > 24) devuelve días y así sucesivamente.

¿Cómo debo ir sobre esto?

EDITAR: La respuesta aceptada actual ha hecho exactamente lo que quería hacer. Lo recomiendo para un uso fácil para obtener el tiempo entre dos fechas en la forma que utiliza la función PHP time() . Si no está particularmente familiarizado con PHP, ese es el tiempo en segundos a partir del 1 de enero de 1970. Esto es beneficioso para un backend en PHP. Si tal vez estás usando un backend como NodeJS, tal vez quieras considerar algunas de las otras opciones que encontrarás a continuación.

Xcode 9.3 • Swift 4.1

Puede usar Calendar para ayudarlo a crear una extensión para hacer sus cálculos de fecha de la siguiente manera:

 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 amount of nanoseconds from another date func nanoseconds(from date: Date) -> Int { return Calendar.current.dateComponents([.nanosecond], from: date, to: self).nanosecond ?? 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" } if nanoseconds(from: date) > 0 { return "\(nanoseconds(from: date))ns" } return "" } } 

Usar el formateador de componentes de fecha

 let dateComponentsFormatter = DateComponentsFormatter() dateComponentsFormatter.allowedUnits = [.year,.month,.weekOfMonth,.day,.hour,.minute,.second] // Cannot add in .nanosecond here (⬆︎) as Swift 4.1 does not consider nanoseconds a calendrical unit 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 nanoseconds = date2.nanoseconds(from: date1) // 23,590,800,000,000,000 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" 

Si alguien necesitara mostrar todas las unidades de tiempo, por ejemplo, “horas minutos segundos”, no solo “horas”. Digamos que la diferencia de tiempo entre dos fechas es de 1 hora, 59 minutos y 20 segundos. Esta función mostrará “1h 59m 20s”.

Aquí está mi código:

 extension NSDate { func offsetFrom(date : NSDate) -> String { let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second] let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: []) let seconds = "\(difference.second)s" let minutes = "\(difference.minute)m" + " " + seconds let hours = "\(difference.hour)h" + " " + minutes let days = "\(difference.day)d" + " " + hours if difference.day > 0 { return days } if difference.hour > 0 { return hours } if difference.minute > 0 { return minutes } if difference.second > 0 { return seconds } return "" } } 

En Swift 3:

 extension Date { func offsetFrom(date : Date) -> String { let dayHourMinuteSecond: Set = [.day, .hour, .minute, .second] let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self); let seconds = "\(difference.second ?? 0)s" let minutes = "\(difference.minute ?? 0)m" + " " + seconds let hours = "\(difference.hour ?? 0)h" + " " + minutes let days = "\(difference.day ?? 0)d" + " " + hours if let day = difference.day, day > 0 { return days } if let hour = difference.hour, hour > 0 { return hours } if let minute = difference.minute, minute > 0 { return minutes } if let second = difference.second, second > 0 { return seconds } return "" } } 

Usted pregunta:

Me gustaría tener una función que compare las dos fechas y si (segundos> 60) luego devuelve minutos, si (minutos> 60) devuelve horas y si (horas> 24) devuelve días y así sucesivamente.

Supongo que está intentando construir una representación en cadena del tiempo transcurrido entre dos fechas. En lugar de escribir su propio código para hacer eso, Apple ya tiene una clase diseñada para hacer precisamente eso. A saber, use DateComponentsFormatter , configure allowedUnits a los valores que tengan sentido para su aplicación, establezca unitsStyle en lo que desee (por ejemplo, .full ) y luego llame a string(from:to:) .

Por ejemplo, en 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) 

Esto también localizará la cadena apropiada para el dispositivo en cuestión.

O bien, en 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) 

Si está buscando los valores numéricos reales, simplemente use dateComponents . Por ejemplo, en Swift 3:

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

O bien, en Swift 2.3:

 let components = NSCalendar.currentCalendar().components([.Month, .Day, .Hour, .Minute, .Second], fromDate: previousDate, toDate: now, options: []) 
  func dateDiff(dateStr:String) -> String { var f:NSDateFormatter = NSDateFormatter() f.timeZone = NSTimeZone.localTimeZone() f.dateFormat = "yyyy-M-dd'T'HH:mm:ss.SSSZZZ" var now = f.stringFromDate(NSDate()) var startDate = f.dateFromString(dateStr) var endDate = f.dateFromString(now) var calendar: NSCalendar = NSCalendar.currentCalendar() let calendarUnits = NSCalendarUnit.CalendarUnitWeekOfMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute | NSCalendarUnit.CalendarUnitSecond let dateComponents = calendar.components(calendarUnits, fromDate: startDate!, toDate: endDate!, options: nil) let weeks = abs(dateComponents.weekOfMonth) let days = abs(dateComponents.day) let hours = abs(dateComponents.hour) let min = abs(dateComponents.minute) let sec = abs(dateComponents.second) var timeAgo = "" if (sec > 0){ if (sec > 1) { timeAgo = "\(sec) Seconds Ago" } else { timeAgo = "\(sec) Second Ago" } } if (min > 0){ if (min > 1) { timeAgo = "\(min) Minutes Ago" } else { timeAgo = "\(min) Minute Ago" } } if(hours > 0){ if (hours > 1) { timeAgo = "\(hours) Hours Ago" } else { timeAgo = "\(hours) Hour Ago" } } if (days > 0) { if (days > 1) { timeAgo = "\(days) Days Ago" } else { timeAgo = "\(days) Day Ago" } } if(weeks > 0){ if (weeks > 1) { timeAgo = "\(weeks) Weeks Ago" } else { timeAgo = "\(weeks) Week Ago" } } print("timeAgo is===> \(timeAgo)") return timeAgo; } 

Agregué una versión “larga” a la respuesta de Leo Dabus en caso de que quieras tener una cadena que diga algo así como “hace 2 semanas” en lugar de solo “2w” …

 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([.weekOfYear], from: date, to: self).weekOfYear ?? 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 "" } func offsetLong(from date: Date) -> String { if years(from: date) > 0 { return years(from: date) > 1 ? "\(years(from: date)) years ago" : "\(years(from: date)) year ago" } if months(from: date) > 0 { return months(from: date) > 1 ? "\(months(from: date)) months ago" : "\(months(from: date)) month ago" } if weeks(from: date) > 0 { return weeks(from: date) > 1 ? "\(weeks(from: date)) weeks ago" : "\(weeks(from: date)) week ago" } if days(from: date) > 0 { return days(from: date) > 1 ? "\(days(from: date)) days ago" : "\(days(from: date)) day ago" } if hours(from: date) > 0 { return hours(from: date) > 1 ? "\(hours(from: date)) hours ago" : "\(hours(from: date)) hour ago" } if minutes(from: date) > 0 { return minutes(from: date) > 1 ? "\(minutes(from: date)) minutes ago" : "\(minutes(from: date)) minute ago" } if seconds(from: date) > 0 { return seconds(from: date) > 1 ? "\(seconds(from: date)) seconds ago" : "\(seconds(from: date)) second ago" } return "" } } 

Extensión combinada + FechaComponentesFormatter de la respuesta de @ leo-dabus

Xcode 8.3 • Swift 3.1

 extension DateComponentsFormatter { func difference(from fromDate: Date, to toDate: Date) -> String? { self.allowedUnits = [.year,.month,.weekOfMonth,.day] self.maximumUnitCount = 1 self.unitsStyle = .full return self.string(from: fromDate, to: toDate) } } let dateComponentsFormatter = DateComponentsFormatter() dateComponentsFormatter.difference(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month" 

Código ligeramente modificado para Swift 3.0

 let calendar = NSCalendar.current as NSCalendar // Replace the hour (time) of both dates with 00:00 let date1 = calendar.startOfDay(for: startDateTime) let date2 = calendar.startOfDay(for: endDateTime) let flags = NSCalendar.Unit.day let components = calendar.components(flags, from: date1, to: date2, options: []) return components.day! 

Con Swift 3, de acuerdo con sus necesidades, puede elegir una de las dos formas siguientes de resolver su problema.


1. Muestra la diferencia entre dos fechas para el usuario

Puede usar DateComponentsFormatter para crear cadenas para la interfaz de su aplicación. DateComponentsFormatter tiene una propiedad maximumUnitCount con la siguiente statement:

 var maximumUnitCount: Int { get set } 

Utilice esta propiedad para limitar el número de unidades que se muestran en la cadena resultante. Por ejemplo, con esta propiedad establecida en 2, en lugar de “1h 10m, 30s”, la cadena resultante sería “1h 10m”. Utilice esta propiedad cuando tenga restricciones de espacio o desee redondear los valores a la unidad grande más cercana.

Al establecer el valor de maximumUnitCount en 1 , tiene la garantía de mostrar la diferencia en una DateComponentsFormatter unidad de DateComponentsFormatter (años, meses, días, horas o minutos).

El código de Playground a continuación muestra cómo mostrar la diferencia entre dos fechas:

 import Foundation let oldDate = Date(timeIntervalSinceReferenceDate: -16200) let newDate = Date(timeIntervalSinceReferenceDate: 0) let dateComponentsFormatter = DateComponentsFormatter() dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute] dateComponentsFormatter.maximumUnitCount = 1 dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full let timeDifference = dateComponentsFormatter.string(from: oldDate, to: newDate) print(String(reflecting: timeDifference)) // prints Optional("5 hours") 

Tenga en cuenta que DateComponentsFormatter redondea el resultado. Por lo tanto, una diferencia de 4 horas y 30 minutos se mostrará como 5 horas .

Si necesita repetir esta operación, puede refactorizar su código:

 import Foundation struct Formatters { static let dateComponentsFormatter: DateComponentsFormatter = { let dateComponentsFormatter = DateComponentsFormatter() dateComponentsFormatter.allowedUnits = [NSCalendar.Unit.year, .month, .day, .hour, .minute] dateComponentsFormatter.maximumUnitCount = 1 dateComponentsFormatter.unitsStyle = DateComponentsFormatter.UnitsStyle.full return dateComponentsFormatter }() } extension Date { func offset(from: Date) -> String? { return Formatters.dateComponentsFormatter.string(from: oldDate, to: self) } } let oldDate = Date(timeIntervalSinceReferenceDate: -16200) let newDate = Date(timeIntervalSinceReferenceDate: 0) let timeDifference = newDate.offset(from: oldDate) print(String(reflecting: timeDifference)) // prints Optional("5 hours") 

2. Obtenga la diferencia entre dos fechas sin formatear

Si no necesita mostrar el formato de la diferencia entre dos fechas para el usuario, puede usar el Calendar . Calendar tiene un método dateComponents(_:from:to:) que tiene la siguiente statement:

 func dateComponents(_ components: Set, from start: Date, to end: Date) -> DateComponents 

Devuelve la diferencia entre dos fechas.

El siguiente código de Playground que usa dateComponents(_:from:to:) muestra cómo recuperar la diferencia entre dos fechas devolviendo la diferencia en un solo tipo de Calendar.Component (años, meses, días, horas o minutos).

 import Foundation let oldDate = Date(timeIntervalSinceReferenceDate: -16200) let newDate = Date(timeIntervalSinceReferenceDate: 0) let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute] let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: oldDate, to: newDate) let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) } for (component, value) in arrayOfTuples { if let value = value, value > 0 { print(component, value) // prints hour 4 break } } 

Si necesita repetir esta operación, puede refactorizar su código:

 import Foundation extension Date { func offset(from: Date) -> (Calendar.Component, Int)? { let descendingOrderedComponents = [Calendar.Component.year, .month, .day, .hour, .minute] let dateComponents = Calendar.current.dateComponents(Set(descendingOrderedComponents), from: from, to: self) let arrayOfTuples = descendingOrderedComponents.map { ($0, dateComponents.value(for: $0)) } for (component, value) in arrayOfTuples { if let value = value, value > 0 { return (component, value) } } return nil } } let oldDate = Date(timeIntervalSinceReferenceDate: -16200) let newDate = Date(timeIntervalSinceReferenceDate: 0) if let (component, value) = newDate.offset(from: oldDate) { print(component, value) // prints hour 4 } 

En Swift 2.2

  /// Returns the amount of years from another date func years(fromdate: NSDate) -> Int { return NSCalendar.currentCalendar().components([.Year], fromDate: fromdate, toDate: NSDate(), options: []).year ?? 0 } /// Returns the amount of months from another date func months(fromdate: NSDate) -> Int { return NSCalendar.currentCalendar().components([.Month], fromDate: fromdate, toDate: NSDate(), options: []).month ?? 0 } /// Returns the amount of weeks from another date func weeks(fromdate: NSDate) -> Int { return NSCalendar.currentCalendar().components([.WeekOfYear], fromDate: fromdate, toDate: NSDate(), options: []).weekOfYear ?? 0 } /// Returns the amount of days from another date func days(fromdate: NSDate) -> Int { return NSCalendar.currentCalendar().components([.Day], fromDate: fromdate, toDate: NSDate(), options: []).day ?? 0 } /// Returns the amount of hours from another date func hours(fromdate: NSDate) -> Int { return NSCalendar.currentCalendar().components([.Hour], fromDate: fromdate, toDate: NSDate(), options: []).hour ?? 0 } /// Returns the amount of minutes from another date func minutes(fromdate: NSDate) -> Int { return NSCalendar.currentCalendar().components([.Minute], fromDate: fromdate, toDate: NSDate(), options: []).minute ?? 0 } /// Returns the amount of seconds from another date func seconds(fromdate: NSDate) -> Int { return NSCalendar.currentCalendar().components(.Second, fromDate: fromdate, toDate: NSDate(), options: []).second ?? 0 } 

Aquí está mi respuesta para las respuestas Swift 3 anteriores. Esto es actual a partir de noviembre de 2016, el lanzamiento de Xcode fue de 8.2 Beta (8C23). Usó algunas de las sugerencias de Sagar y Emin anteriores y algunas veces tuvo que dejar que Xcode se autocompletara para sugerir la syntax. Parecía que la syntax realmente cambió a esta versión beta. buyDate que recibí de un DatePicker:

 let calendar = NSCalendar.current as NSCalendar let currentDate = Date() let date1 = calendar.startOfDay(for: buyDate!) let date2 = calendar.startOfDay(for: currentDate) let flags = NSCalendar.Unit.day let components = calendar.components(flags, from: date1, to: date2) NSLog(" day= \(components.day)") 

Una pequeña adición a la respuesta de Leo Dabus para proporcionar las versiones en plural y ser más legible para los humanos.

Swift 3

 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) == 1 { return "\(years(from: date)) year" } else if years(from: date) > 1 { return "\(years(from: date)) years" } if months(from: date) == 1 { return "\(months(from: date)) month" } else if months(from: date) > 1 { return "\(months(from: date)) month" } if weeks(from: date) == 1 { return "\(weeks(from: date)) week" } else if weeks(from: date) > 1 { return "\(weeks(from: date)) weeks" } if days(from: date) == 1 { return "\(days(from: date)) day" } else if days(from: date) > 1 { return "\(days(from: date)) days" } if hours(from: date) == 1 { return "\(hours(from: date)) hour" } else if hours(from: date) > 1 { return "\(hours(from: date)) hours" } if minutes(from: date) == 1 { return "\(minutes(from: date)) minute" } else if minutes(from: date) > 1 { return "\(minutes(from: date)) minutes" } return "" } } 

Si su propósito es obtener el número exacto del día entre dos fechas, puede solucionar este problema de esta manera:

 // Assuming that firstDate and secondDate are defined // ... var calendar: NSCalendar = NSCalendar.currentCalendar() // Replace the hour (time) of both dates with 00:00 let date1 = calendar.startOfDayForDate(firstDate) let date2 = calendar.startOfDayForDate(secondDate) let flags = NSCalendarUnit.DayCalendarUnit let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil) components.day // This will return the number of day(s) between dates 

Esta es la versión más corta: básicamente trato de obtener la diferencia entre la marca de tiempo posterior a la Date() ahora.

 // MARK: - UPDATE Time Stamp static func updateTimeStampPost(postTimeStamp: Date?, _ completion: (_ finalString: String?) -> Void) { // date in the current state let date = Date() let dateComponentFormatter = DateComponentsFormatter() // change the styling date, wether second minute or hour dateComponentFormatter.unitsStyle = .abbreviated dateComponentFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth] dateComponentFormatter.maximumUnitCount = 1 // return the date new format as a string in the completion completion(dateComponentFormatter.string(from: postTimeStamp!, to: date)) } 

Para XCode Versión 8.3.3 y 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)") 

Algunas adiciones en jose920405 responden para que sea compatible con Swift 3.0 y superior

 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([.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 minutes < 2 { timeAgo = "Hour Ago" } else{ timeAgo = "\(hours) Hours Ago" } } if (days > 0) { if minutes < 2 { timeAgo = "Day Ago" } else{ timeAgo = "\(days) Days Ago" } } if(months > 0){ if minutes < 2 { timeAgo = "Month Ago" } else{ timeAgo = "\(months) Months Ago" } } if(years > 0){ if minutes < 2 { timeAgo = "Year Ago" } else{ timeAgo = "\(years) Years Ago" } } DLog("timeAgo is ===> \(timeAgo)") return timeAgo; }