How to Compare Two Dates (Nsdate) in Swift 3 and Get The Days Between Them

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



Leave a reply



Submit