Fast days between two NSDates

I am wondering if there is any new and terrific opportunity to get the number of days between two NSDates in Swift / "new" Cocoa?

eg. as in Ruby, I would do:

(end_date - start_date).to_i 
+90
date ios swift date-difference
Jul 13 '14 at
source share
25 answers

The accepted answer will not return the correct day number between two dates. You should also consider the time difference. For example, if you compare the dates 2015-01-01 10:00 and 2015-01-02 09:00 , the days between these dates will return as 0 (zero), since the difference between these dates is less than 24 hours (this is 23 hours) .

If your goal is to get the exact number of days between two dates, you can work around this problem as follows:

 // 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 and Swift 4 Version

 let calendar = Calendar.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) 
+201
Jan 27 '15 at 5:03
source share

Here is my answer for 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 } 
+48
Aug 23 '15 at 9:33
source share

I see a couple of Swift3 answers, so I will add my own:

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

The naming seems more Swifty, it is one line and uses the last method dateComponents() .

+36
Aug 16 '16 at 19:40
source share

I translated my Objective-C answer

 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) 

Result

 <NSDateComponents: 0x10280a8a0> Day: 4 

The hardest part was that autocomplete insists that fromDate and toDate will be NSDate? but really they must be NSDate! as shown in the link.

I don’t see what a good solution with an operator will look like, since you want to specify a unit separately in each case. You can return the time interval, but do not get much.

+29
Jul 13 '14 at 17:37
source share

It’s very nice here, extending Date to get the difference between dates in years, months, days, hours, minutes, seconds

 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 } } 
+23
Aug 18 '17 at 13:30
source share

Update for 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! } 
+18
Aug 08 '16 at 14:23
source share

Here is the answer for Swift 3 (tested on 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! } 

Then you can call it as follows

 let pickedDate: Date = sender.date let NumOfDays: Int = daysBetweenDates(startDate: pickedDate, endDate: Date()) print("Num of Days: \(NumOfDays)") 
+9
Jul 24 '16 at 6:44
source share

Swift 3. Thanks to Emin Buğra Saral above for the startOfDay offer.

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

Using:

 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 
+7
Jan 22 '17 at 0:09
source share

Everything that was built into the fast is still very simple. Because they should be at this early stage. But you can add your own material with the risk associated with operator overloading and global domain functions. However, they will be local to your module.

 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 
+3
Jul 13 '14 at 16:33
source share

Here is my answer for 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! } 
+3
Oct 02 '16 at 2:29
source share

There is hardly a standard Swift library; just meager basic numerical, string, and collectible types.

You can perfectly define such abbreviations using extensions, but as far as real APIs are concerned, there is no “new” Cocoa; Swift simply maps directly to Cocoa's old, detailed APIs that already exist.

+2
Jul 13 '14 at 16:36
source share

I am going to add my version, although this thread is already a year old. My code is as follows:

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

I hope this helps someone.

Greetings

+2
Jul 08 '15 at 10:47
source share

The Erin method, upgraded to Swift 3, shows the days from today (excluding the time of day)

 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! } 
+2
Aug 28 '16 at 2:02
source share

This returns the absolute difference in days between some Date and today:

 extension Date { func daysFromToday() -> Int { return abs(Calendar.current.dateComponents([.day], from: self, to: Date()).day!) } } 

and then use this:

 if someDate.daysFromToday() >= 7 { // at least a week from today } 
+2
Aug 10 '18 at 17:15
source share

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) } } 
+1
Jun 12 '17 at 8:07
source share

The whole answer is good. But for localizations, we need to calculate the number of decimal days between two dates. therefore, we can provide a stable decimal format.

 // 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 } 
+1
Mar 11 '18 at 20:15
source share
 extension Date { func daysFromToday() -> Int { return Calendar.current.dateComponents([.day], from: self, to: Date()).day! } } 

Then use it like

  func dayCount(dateString: String) -> String{ let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MMM dd,yyyy hh:mm a" let fetchedDate = dateFormatter.date(from: dateString) let day = fetchedDate?.daysFromToday() if day! > -1{ return "\(day!) days passed." }else{ return "\(day! * -1) days left." } } 
+1
Jun 20 '19 at 16:24
source share

Swift 3 - days from today to 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! } 

Call function like this

 // Days from today until date var examnDate = DateComponents() examnDate.year = 2016 examnDate.month = 12 examnDate.day = 15 let daysCount = daysUntilDate(endDateComponents: examnDate) 
0
Nov 23 '16 at 23:46
source share

it would be easier to create an extension by date

 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! } } 
0
Jan 11 '17 at 10:23
source share
  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)) } 

if you need year, month, days and hours, use the line

var tomorrow = Calendar.current.date (byAdding: .day, value: 1, to: Date ())!

let dc = future.completeOffset (from: Date ())

0
Mar 15 '18 at 18:27
source share

Nice comfortable liner:

 extension Date { var daysFromNow: Int { return Calendar.current.dateComponents([.day], from: Date(), to: self).day! } } 
0
Jul 05 '18 at 23:54
source share

Swift 4

  func getDateHeader(indexPath: Int) -> String { let formatter2 = DateFormatter() formatter2.dateFormat = "MM-dd-yyyy" var dateDeadline : Date? dateDeadline = formatter2.date(from: arrCompletedDate[indexPath] as! String) let currentTime = dateDeadline?.unixTimestamp let calendar = NSCalendar.current let date = NSDate(timeIntervalSince1970: Double(currentTime!)) if calendar.isDateInYesterday(date as Date) { return "Yesterday" } else if calendar.isDateInToday(date as Date) { return "Today" } else if calendar.isDateInTomorrow(date as Date) { return "Tomorrow" } else { let startOfNow = calendar.startOfDay(for: NSDate() as Date) let startOfTimeStamp = calendar.startOfDay(for: date as Date) let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp) let day = components.day! if day < 1 { return "\(abs(day)) days ago" } else { return "In \(day) days" } } } 
0
Oct 26 '18 at 7:37
source share

You can use the following extension:

 public extension Date { func daysTo(_ date: Date) -> Int? { let calendar = Calendar.current // Replace the hour (time) of both dates with 00:00 let date1 = calendar.startOfDay(for: self) let date2 = calendar.startOfDay(for: date) let components = calendar.dateComponents([.day], from: date1, to: date2) return components.day // This will return the number of day(s) between dates } } 

Then you can call it like this:

 startDate.daysTo(endDate) 
0
Aug 24 '19 at 22:05
source share

Version 2017, copy and paste

 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 } } 
-one
Jul 20 '17 at 23:00
source share
 let calendar = NSCalendar.currentCalendar(); let component1 = calendar.component(.Day, fromDate: fromDate) let component2 = calendar.component(.Day, fromDate: toDate) let difference = component1 - component2 
-2
Jul 01 '16 at 6:35
source share



All Articles