Ollie Ollie - 6 months ago 58
iOS Question

NSDate crashing on simulators less than 5s on versions iOS 8.4 and 9.3

I'm having a strange bug where my application will crash on all simulators less than the iPhone 5s.

Firstly, I've tried resetting all the simulators and the crash still persists.

Code



extension NSDate {

func firstDayOfMonth() -> NSDate {
let cal = NSCalendar.currentCalendar()
let comp = cal.components([.Year, .Month], fromDate: self)

// to 12pm
comp.hour = 12
comp.minute = 0
comp.second = 0

return cal.dateFromComponents(comp)!
}


func lastDayOfMonth() -> NSDate {
let cal = NSCalendar.currentCalendar()
let comp = NSDateComponents()

comp.month = 1
comp.day -= 1

// to 12pm
comp.hour = 12
comp.minute = 0
comp.second = 0

return cal.dateByAddingComponents(comp, toDate: self.firstDayOfMonth()!, options: [])!
}
}





The Error



The final line of code in the second function:

cal.dateByAddingComponents(comp, toDate: self.firstDayOfMonth()!, options: [])!

returns
5828963-12-20 00:00:00 +0000
on the devices where the crash occurs.




Reproducing the Error



I'm able to consistently reproduce the issue when running on the iPhone 4s (v8.4, v9.3) and iPhone 5 (v8.4, v9.3) however the error does not occur in the playground or on the iPhone 5s or iPhone 6/6s

Any help would be much appreciated.

Answer

Please try this alternative date math

extension NSDate {

  func firstDayOfMonth() -> NSDate {

    let calendar = NSCalendar.currentCalendar()
    var startDate : NSDate?
    calendar.rangeOfUnit(.Month, startDate: &startDate, interval: nil, forDate: self)
    let components = calendar.components([.Year, .Month, .Day], fromDate: startDate!)
    components.hour = 12
    return calendar.dateFromComponents(components)!
  }

  func lastDayOfMonth() -> NSDate {

    let calendar = NSCalendar.currentCalendar()
    let dayRange = calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: self)
    let dayLength = dayRange.length
    let components = calendar.components([.Year, .Month, .Day], fromDate: self)
    components.day = dayLength
    components.hour = 12
    return calendar.dateFromComponents(components)!
  }
}