How can i compare two dates (NSDate) in Swift 3 and get the days between them?
Simply make extension of Date
like this and get difference in days.
extension Date {
func daysBetweenDate(toDate: Date) -> Int {
let components = Calendar.current.dateComponents([.day], from: self, to: toDate)
return components.day ?? 0
}
}
Now use this extension like this
let numOfDays = fromDate.daysBetweenDate(toDate: toDate)
You can use DateFormatter
to convert String to Date like this.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
let date = dateFormatter.date(from: "18-11-2016")
Swift days between two NSDates
You have to consider the time difference as well. For example if you compare the dates 2015-01-01 10:00
and 2015-01-02 09:00
, days between those dates will return as 0 (zero) since the difference between those dates is less than 24 hours (it's 23 hours).
If your purpose is to get the exact day number between two dates, you can work around this issue like this:
// 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)
Swift 3 - find number of calendar days between two dates
Turns out this is much simpler to do in Swift 3:
extension Date {
func interval(ofComponent comp: Calendar.Component, fromDate date: Date) -> Int {
let currentCalendar = Calendar.current
guard let start = currentCalendar.ordinality(of: comp, in: .era, for: date) else { return 0 }
guard let end = currentCalendar.ordinality(of: comp, in: .era, for: self) else { return 0 }
return end - start
}
}
Edit
Comparing the ordinality of the two dates should be within the same era
instead of the same year
, since naturally the two dates may fall in different years.
Usage
let yesterday = Date(timeInterval: -86400, since: Date())
let tomorrow = Date(timeInterval: 86400, since: Date())
let diff = tomorrow.interval(ofComponent: .day, fromDate: yesterday)
// return 2
Swift 3 - Comparing Date objects
I have tried this snippet (in Xcode 8 Beta 6), and it is working fine.
let date1 = Date()
let date2 = Date().addingTimeInterval(100)
if date1 == date2 { ... }
else if date1 > date2 { ... }
else if date1 < date2 { ... }
NSDate Comparison using Swift
I like using extensions to make code more readable. Here are a few NSDate extensions that can help clean your code up and make it easy to understand. I put this in a sharedCode.swift file:
extension NSDate {
func isGreaterThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isGreater = false
//Compare Values
if self.compare(dateToCompare as Date) == ComparisonResult.orderedDescending {
isGreater = true
}
//Return Result
return isGreater
}
func isLessThanDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isLess = false
//Compare Values
if self.compare(dateToCompare as Date) == ComparisonResult.orderedAscending {
isLess = true
}
//Return Result
return isLess
}
func equalToDate(dateToCompare: NSDate) -> Bool {
//Declare Variables
var isEqualTo = false
//Compare Values
if self.compare(dateToCompare as Date) == ComparisonResult.orderedSame {
isEqualTo = true
}
//Return Result
return isEqualTo
}
func addDays(daysToAdd: Int) -> NSDate {
let secondsInDays: TimeInterval = Double(daysToAdd) * 60 * 60 * 24
let dateWithDaysAdded: NSDate = self.addingTimeInterval(secondsInDays)
//Return Result
return dateWithDaysAdded
}
func addHours(hoursToAdd: Int) -> NSDate {
let secondsInHours: TimeInterval = Double(hoursToAdd) * 60 * 60
let dateWithHoursAdded: NSDate = self.addingTimeInterval(secondsInHours)
//Return Result
return dateWithHoursAdded
}
}
Now if you can do something like this:
//Get Current Date/Time
var currentDateTime = NSDate()
//Get Reminder Date (which is Due date minus 7 days lets say)
var reminderDate = dueDate.addDays(-7)
//Check if reminderDate is Greater than Right now
if(reminderDate.isGreaterThanDate(currentDateTime)) {
//Do Something...
}
Comparing two NSDates day, month and year integers
NSCalendar
has a method isDate:equalToDate:toUnitGranularity:
which does exactly what you need
date1
and date2
are the NSDate
instances to be compared, the result is Bool
let calendar = NSCalendar.currentCalendar()
calendar.timeZone = NSTimeZone(forSecondsFromGMT: 0)
let datesAreInTheSameDay = calendar.isDate(date1, equalToDate: date2, toUnitGranularity: .CalendarUnitDay | .CalendarUnitMonth | .CalendarUnitYear)
Swift 2:
let datesAreInTheSameDay = calendar.isDate(date1, equalToDate: date2, toUnitGranularity: [.Day, .Month, .Year])
Swift 3:
var calendar = Calendar.current
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
let datesAreInTheSameDay = calendar.isDate(date1, equalTo: date2, toGranularity:.day)
Getting the difference between two Dates (months/days/hours/minutes/seconds) in Swift
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, .year]
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"
Comparing NSDates without time component
Use this Calendar
function to compare dates in iOS 8.0+
func compare(_ date1: Date, to date2: Date, toGranularity component: Calendar.Component) -> ComparisonResult
passing .day
as the unit
Use this function as follows:
let now = Date()
// "Sep 23, 2015, 10:26 AM"
let olderDate = Date(timeIntervalSinceNow: -10000)
// "Sep 23, 2015, 7:40 AM"
var order = Calendar.current.compare(now, to: olderDate, toGranularity: .hour)
switch order {
case .orderedDescending:
print("DESCENDING")
case .orderedAscending:
print("ASCENDING")
case .orderedSame:
print("SAME")
}
// Compare to hour: DESCENDING
var order = Calendar.current.compare(now, to: olderDate, toGranularity: .day)
switch order {
case .orderedDescending:
print("DESCENDING")
case .orderedAscending:
print("ASCENDING")
case .orderedSame:
print("SAME")
}
// Compare to day: SAME
How can i calculate the days between two dates?
Try this code, updated for Swift 2.0
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let first = "2010-09-01"
let firstDate = dateFormatter.dateFromString(first)!
let last = "2010-09-05"
let lastDate = dateFormatter.dateFromString(last)!
let currentCalendar = NSCalendar.currentCalendar()
let timeUnitDay = NSCalendarUnit.Day
let daysBetween = currentCalendar.components(timeUnitDay, fromDate: firstDate, toDate: lastDate, options: NSCalendarOptions.MatchStrictly)
print(daysBetween.day)
Related Topics
Cmlogitem Timestamp: Why So Complicated
Override UIgesturerecognizer Touchesbegan
Module Compiled with Swift X.1 Cannot Be Imported in Swift X.0.2
Struct Memberwise Initialization - Omitting Values for Properties That Have Defaults
Get Output Frames Failed, State 8196
Instantiating a Nested Class Using Nsclassfromstring in Swift
Event Scrolling (Scrollviewdidscroll) Never Called - Swift 3
Swift Codable: Decode Dictionary with Unknown Keys
Nstextfield Non-System-Font Content Clipped When Usessinglelinemode Is True
How to Access The Firebase Topics a User Is Subscribed To
How to Put View on Top of All Other Views in Swiftui
iOS Swift, Aws Cognito User Pool, Unable to Refresh Access Token
Convert/Wrap Swift Struct as Nsvalue for Caanimation Purposes
iOS App Extension - Action - Custom Data