ios swift date date-difference

ios - Días rápidos entre dos NSDates



swift date-difference (20)

Me pregunto si hay alguna posibilidad nueva e increíble de obtener la cantidad de días entre dos NSDates en Swift / el "nuevo" Cocoa.

Por ejemplo, como en Ruby, yo haría:

(end_date - start_date).to_i


Versión 2017, copiar y pegar

func simpleIndex(ofDate: Date) -> Int { // index here just means today 0, yesterday -1, tomorrow 1 etc. let c = Calendar.current let todayRightNow = Date() let d = c.date(bySetting: .hour, value: 13, of: ofDate) let t = c.date(bySetting: .hour, value: 13, of: todayRightNow) if d == nil || today == nil { print("weird problem simpleIndex#ofDate") return 0 } let r = c.dateComponents([.day], from: today!, to: d!) // yesterday is negative one, tomorrow is one if let o = r.value(for: .day) { return o } else { print("another weird problem simpleIndex#ofDate") return 0 } }


Actualización para Swift 3 iOS 10 Beta 4

func daysBetweenDates(startDate: Date, endDate: Date) -> Int { let calendar = Calendar.current let components = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate) return components.day! }


Apenas existe una biblioteca estándar específica de Swift; solo los tipos numéricos, de cuerda y de recolección básicos simples.

Es perfectamente posible definir tales atajos utilizando extensiones, pero en lo que respecta a las API listas para usar, no hay un "nuevo" Cacao; Swift simplemente se asigna directamente a las mismas antiguas y caros API de Cocoa, como ya existen.


Aquí está la respuesta para Swift 3 (probado para IOS 10 Beta)

func daysBetweenDates(startDate: Date, endDate: Date) -> Int { let calendar = Calendar.current let components = calendar.components([.day], from: startDate, to: endDate, options: []) return components.day! }

Entonces puedes llamarlo así

let pickedDate: Date = sender.date let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date()) print("Num of Days: /(NumOfDays)")


Aquí está mi respuesta para Swift 2:

func daysBetweenDates(startDate: NSDate, endDate: NSDate) -> Int { let calendar = NSCalendar.currentCalendar() let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: []) return components.day }


Aquí está mi respuesta para Swift 3:

func daysBetweenDates(startDate: NSDate, endDate: NSDate, inTimeZone timeZone: TimeZone? = nil) -> Int { var calendar = Calendar.current if let timeZone = timeZone { calendar.timeZone = timeZone } let dateComponents = calendar.dateComponents([.day], from: startDate.startOfDay, to: endDate.startOfDay) return dateComponents.day! }


Aquí está muy bien, extensión de Date para obtener la diferencia entre las fechas en años, meses, días, horas, minutos, segundos

extension Date { func years(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.year], from: sinceDate, to: self).year } func months(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.month], from: sinceDate, to: self).month } func days(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.day], from: sinceDate, to: self).day } func hours(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.hour], from: sinceDate, to: self).hour } func minutes(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.minute], from: sinceDate, to: self).minute } func seconds(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.second], from: sinceDate, to: self).second } }


La respuesta aceptada no devolverá el número de día correcto entre dos fechas. También debes considerar la diferencia de tiempo. Por ejemplo, si compara las fechas 2015-01-01 10:00 y 2015-01-02 09:00 , los días entre esas fechas volverán a ser 0 (cero) ya que la diferencia entre esas fechas es menos de 24 horas (es 23 horas).

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 // ... let calendar = 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.Day let components = calendar.components(flags, fromDate: date1, toDate: date2, options: []) components.day // This will return the number of day(s) between dates

Versión de Swift 3

let calendar = NSCalendar.current // Replace the hour (time) of both dates with 00:00 let date1 = calendar.startOfDay(for: firstDate) let date2 = calendar.startOfDay(for: secondDate) let components = calendar.dateComponents([.day], from: date1, to: date2)


Las cosas incorporadas rápidamente son muy básicas. Como deberían ser en esta etapa temprana. Pero puede agregar sus propias cosas con el riesgo que entraña la sobrecarga de operadores y las funciones de dominio global. Sin embargo, serán locales para tu módulo.

let now = NSDate() let seventies = NSDate(timeIntervalSince1970: 0) // Standard solution still works let days = NSCalendar.currentCalendar().components(.CalendarUnitDay, fromDate: seventies, toDate: now, options: nil).day // Flashy swift... maybe... func -(lhs:NSDate, rhs:NSDate) -> DateRange { return DateRange(startDate: rhs, endDate: lhs) } class DateRange { let startDate:NSDate let endDate:NSDate var calendar = NSCalendar.currentCalendar() var days: Int { return calendar.components(.CalendarUnitDay, fromDate: startDate, toDate: endDate, options: nil).day } var months: Int { return calendar.components(.CalendarUnitMonth, fromDate: startDate, toDate: endDate, options: nil).month } init(startDate:NSDate, endDate:NSDate) { self.startDate = startDate self.endDate = endDate } } // Now you can do this... (now - seventies).months (now - seventies).days


Método de Erin actualizado a Swift 3, Esto muestra los días a partir de hoy (sin tener en cuenta la hora del día)

func daysBetweenDates( endDate: Date) -> Int let calendar: Calendar = Calendar.current let date1 = calendar.startOfDay(for: Date()) let date2 = calendar.startOfDay(for: secondDate) return calendar.dateComponents([.day], from: date1, to: date2).day! }


Swift 3 - Días desde hoy hasta la fecha

func daysUntilDate(endDateComponents: DateComponents) -> Int { let cal = Calendar.current var components = cal.dateComponents([.era, .year, .month, .day], from: NSDate() as Date) let today = cal.date(from: components) let otherDate = cal.date(from: endDateComponents) components = cal.dateComponents([Calendar.Component.day], from: (today! as Date), to: otherDate!) return components.day! }

Función de llamada como esta

// Days from today until date var examnDate = DateComponents() examnDate.year = 2016 examnDate.month = 12 examnDate.day = 15 let daysCount = daysUntilDate(endDateComponents: examnDate)


Swift 3. Gracias a Emin Buğra Saral anterior por la sugerencia de startOfDay .

extension Date { func daysBetween(date: Date) -> Int { return Date.daysBetween(start: self, end: date) } static func daysBetween(start: Date, end: Date) -> Int { let calendar = Calendar.current // Replace the hour (time) of both dates with 00:00 let date1 = calendar.startOfDay(for: start) let date2 = calendar.startOfDay(for: end) let a = calendar.dateComponents([.day], from: date1, to: date2) return a.value(for: .day)! } }

Uso:

let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" let start = dateFormatter.date(from: "2017-01-01")! let end = dateFormatter.date(from: "2018-01-01")! let diff = Date.daysBetween(start: start, end: end) // 365


Swift 3.2

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) } }


Toda respuesta es buena. Pero para Localizaciones necesitamos calcular un número de días decimales entre dos fechas. para que podamos proporcionar el formato decimal sostenible.

// This method returns the fractional number of days between to dates func getFractionalDaysBetweenDates(date1: Date, date2: Date) -> Double { let components = Calendar.current.dateComponents([.day, .hour], from: date1, to: date2) var decimalDays = Double(components.day!) decimalDays += Double(components.hour!) / 24.0 return decimalDays }


Traduje mi respuesta Objective-C

let start = "2010-09-01" let end = "2010-09-05" let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" let startDate:NSDate = dateFormatter.dateFromString(start) let endDate:NSDate = dateFormatter.dateFromString(end) let cal = NSCalendar.currentCalendar() let unit:NSCalendarUnit = .Day let components = cal.components(unit, fromDate: startDate, toDate: endDate, options: nil) println(components)

resultado

<NSDateComponents: 0x10280a8a0> Day: 4

La parte más difícil fue que la autocompletación insiste desde fecha y fecha sería NSDate? , pero de hecho deben ser NSDate! como se muestra en la referencia.

No veo cómo sería una buena solución con un operador, ya que desea especificar la unidad de manera diferente en cada caso. Puede devolver el intervalo de tiempo, pero no ganará mucho.


Veo un par de respuestas de Swift3, así que agregaré la mía:

public static func daysBetween(start: Date, end: Date) -> Int { return Calendar.current.dateComponents([.day], from: start, to: end).day! }

La denominación se siente más Swifty, es una línea y utiliza el último método de dateComponents() .


Voy a agregar mi versión a pesar de que este hilo tiene un año de antigüedad. Mi código se ve así:

var name = txtName.stringValue // Get the users name // Get the date components from the window controls var dateComponents = NSDateComponents() dateComponents.day = txtDOBDay.integerValue dateComponents.month = txtDOBMonth.integerValue dateComponents.year = txtDOBYear.integerValue // Make a Gregorian calendar let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian) // Get the two dates we need var birthdate = calendar?.dateFromComponents(dateComponents) let currentDate = NSDate() var durationDateComponents = calendar?.components(NSCalendarUnit.CalendarUnitDay, fromDate: birthdate!, toDate: currentDate, options: nil) let numberOfDaysAlive = durationDateComponents?.day println("/(numberOfDaysAlive!)") txtGreeting.stringValue = "Hello /(name), You have been alive for /(numberOfDaysAlive!) days."

Espero que esto ayude a alguien.

Aclamaciones,


la opción más fácil sería crear una extensión en Fecha

public extension Date { public var currentCalendar: Calendar { return Calendar.autoupdatingCurrent } public func daysBetween(_ date: Date) -> Int { let components = currentCalendar.dateComponents([.day], from: self, to: date) return components.day! } }


func completeOffset(from date:Date) -> String? { let formatter = DateComponentsFormatter() formatter.unitsStyle = .brief return formatter.string(from: Calendar.current.dateComponents([.year,.month,.day,.hour,.minute,.second], from: date, to: self)) }

si necesita un año, mes, días y horas como cadena, use esto

var tomorrow = Calendar.current.date (porAdición: .day, valor: 1, a: Date ())!

let dc = tomorrow.completeOffset (desde: Fecha ())


let calendar = NSCalendar.currentCalendar(); let component1 = calendar.component(.Day, fromDate: fromDate) let component2 = calendar.component(.Day, fromDate: toDate) let difference = component1 - component2