Search code examples
swiftdatecalendarnsdateformatternsdatecomponents

Get Date by supplying a month and year


I’m trying to create a Date extension static function that accepts two parameters: (month: Int, year: Int) and returns -> Date.

The month that is returned would be its .startOfMonth:

var startOfMonth: Date {
    let calendar = Calendar(identifier: .gregorian)
    let components = calendar.dateComponents([.year, .month], from: self)
    return  calendar.date(from: components)!
}

I know how to retrieve a month in the future by adding n-months to the current:

func addMonths(_ numMonths: Int) -> Date {
    let cal = NSCalendar.current
    return cal.date(byAdding: .month, value: numMonths, to: self)!
}

And I suppose this could be used in a roundabout way to determine what I’m looking for, by first determining how many months from the current is the month I’m interested in getting a Date returned for. But I would much prefer if I could retrieve it without needing to go through this step, especially if there’s a possibility that I’m not actually sure if the month is in fact in the future.


Solution

  • You can use DateComponents initializer to compose a new date just passing the month and year components. Just make sure to pass a calendar as well otherwise the result would be nil. Maybe something like:

    extension Date {
        static func startOfMonth(for month: Int, of year: Int, using calendar: Calendar = .current) -> Date? {
            DateComponents(calendar: calendar, year: year, month: month).date
        }
    }
    
    Date.startOfMonth(for: 2, of: 2021)  // "Feb 1, 2021 at 12:00 AM"