两个NSDates之间的快速天

我想知道是否有一些新的和可怕的可能性来获得Swift /“新”cocoa中两个NSDates之间的天数?

例如像在Ruby中,我会这样做:

(end_date - start_date).to_i 

接受的答案将不会在两个date之间返回正确的date编号。 你也必须考虑时差。 例如,如果比较date2015-01-01 10:002015-01-02 09:00 ,那么这些date之间的天数将返回为0(零),因为这些date之间的差异小于24小时(现在是23小时)。

如果您的目的是要获得两个date之间的确切date编号,您可以像这样解决这个问题:

 // 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 

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) 

这是我对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 } 

我翻译了我的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) 

结果

 <NSDateComponents: 0x10280a8a0> Day: 4 

最难的部分是自动完成从date和date坚持NSDate? ,但的确他们必须是NSDate! 如参考文献所示。

我不知道如何用一个操作符的好解决scheme,因为你想在每种情况下不同地指定单位。 你可以返回时间间隔,但不会获得太多的收益。

我看到一对夫妇Swift3的答案,所以我会加我自己的:

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

命名感觉更Swifty,它是一行,并使用最新的dateComponents()方法。

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

这里是Swift 3的答案(testingIOS 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! } 

那么你可以这样称呼它

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

Swift 3.感谢上面的startOfDay提供的startOfDaybuild议。

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

用法:

 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 

迅速build成的东西还是非常基础的。 因为他们应该在这个早期阶段。 但是,你可以添加自己的东西与重载运营商和全球域function的风险。 他们将在您的模块本地。

 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 

这是我对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! } 

几乎没有任何Swift特定的标准库, 只是精简的基本数字,string和集合types。

使用扩展来定义这样的shorthands是完全可能的,但是就实际的开箱即用API而言,没有“new”Cocoa; Swift只是直接映射到已经存在的旧的详细Cocoa API。

即使这个线程已经过了一年,我也要添加我的版本。 我的代码如下所示:

  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." 

我希望它可以帮助别人。

干杯,

艾琳的方法更新到斯威夫特3,这显示了从今天起的几天(不计时间的一天)

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

斯威夫特3 – 从今天到date

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

调用这样的function

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

更容易的select将是在date上创build一个扩展

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

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

这里是date延长,以获得年,月,日,时,分,秒date之间的差异

 extension Date { func years(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.year], from: date, to: self).year } func months(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.month], from: date, to: self).month } func days(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.day], from: date, to: self).day } func hours(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.hour], from: date, to: self).hour } func minutes(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.minute], from: date, to: self).minute } func seconds(sinceDate: Date) -> Int? { return Calendar.current.dateComponents([.second], from: date, to: self).second } } 
 let calendar = NSCalendar.currentCalendar(); let component1 = calendar.component(.Day, fromDate: fromDate) let component2 = calendar.component(.Day, fromDate: toDate) let difference = component1 - component2 

2017版,复制并粘贴

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