I have a function:
internal func startOfNextMonth() -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.currentCalendar(),
let comp: NSDateComponents = NSDateComponents() else { return nil }
comp.month = 1
comp.day = 0
comp.to12pm()
let date = cal.dateByAddingComponents(comp, toDate: self.startOfMonth()!, options: [])!
return date
}
This should calculate the first day of next month, however it's returning 2016-03-02 08:00:00 UTC
.
Is this something to do with it being a leap year (Feb. 29 messing it up?)
Here's my startOfMonth
function for reference, and the to12pm()
extension:
internal func startOfMonth() -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.autoupdatingCurrentCalendar(),
let comp: NSDateComponents = cal.components([.Year, .Month], fromDate: self.at12pm()!) else { return nil }
comp.to12pm()
return cal.dateFromComponents(comp)!
}
internal extension NSDateComponents {
func to12pm() {
self.hour = 12
self.minute = 0
self.second = 0
}
}
internal func at12pm() -> NSDate? {
let cal = NSCalendar.currentCalendar()
return cal.dateBySettingHour(12, minute: 0, second: 0, ofDate: self, options: [])
}
startOfMonth()
returns first of next month at 12 pm (12:00) then you add another 12 hours in startOfNextMonth()
, this results one day ahead.
NSCalendar
has a smart method to calculate the start of next month regardless of daylight saving changes or other irregularity
let calendar = NSCalendar.currentCalendar()
let components = NSDateComponents()
components.day = 1
let startOfNextMonth = calendar.nextDateAfterDate(NSDate(), matchingComponents: components, options: .MatchNextTime)