Search code examples
nsdateswift3nscalendar

Swift 3 - find number of calendar days between two dates


The way I did this in Swift 2.3 was:

let currentDate         = NSDate()
let currentCalendar     = NSCalendar.currentCalendar()

var startDate : NSDate?
var endDate   : NSDate?

// The following two lines set the `startDate` and `endDate` to the start of the day

currentCalendar.rangeOfUnit(.Day, startDate: &startDate, interval: nil, forDate: currentDate)
currentCalendar.rangeOfUnit(.Day, startDate: &endDate, interval: nil, forDate: self)

let intervalComps = currentCalendar.components([.Day], fromDate: startDate!, toDate: endDate!, options: [])

print(intervalComps.day)

Now this has all changed with Swift 3. I have to either use NSCalendar and NSDate by constantly type casting with as, or find the Swift 3 way of doing it.

What's the right way to do it in Swift 3?


Solution

  • 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