Search code examples
swiftnsdatemutating-function

Swift NSDate Extension Error: Mutating isn't valid on methods in classes or class-bound protocols


I am trying to extending NSDate but am getting two errors :

extension NSDate { //'mutating' isn't valid on methods in classes or class-bound protocols
    mutating func addMonth() {
        let calendar = NSCalendar.currentCalendar()
        let component = NSDateComponents()
        component.month = 1
        self = calendar.dateByAddingComponents(component, toDate: self, options: []) //Cannot assign to value: 'self' is immutable
    }
} 

My guess is that NSDate is a class and not a Swift type and as the error states mutating is not possible on methods in classes. If I return the value and assign it everything works but I want to know the exact reason this is not working and if there is a better workaround.


Solution

  • NSDate objects encapsulate a single point in time, independent of any particular calendrical system or time zone. Date objects are immutable, representing an invariant time interval relative to an absolute reference date (00:00:00 UTC on 1 January 2001).

    NSDate Documentation

    Because NSDate objects are immutable, you can't arbitrarily add a month to one. You could modify your extension to return a new NSDate object from an existing date, with a month added:

    extension NSDate {
        func addMonth() -> NSDate? {
            let calendar = NSCalendar.currentCalendar()
            let component = NSDateComponents()
            component.month = 1
            let newDate = calendar.dateByAddingComponents(component, toDate: self, options: [])
            return newDate
        }
    }