first and last day of the current month in swift first and last day of the current month in swift ios ios

first and last day of the current month in swift


Swift 3 and 4 drop-in extensions

This actually gets a lot easier with Swift 3+:

  1. You can do it without guard (you could if you wanted to, but because DateComponents is a non-optional type now, it's no longer necessary).
  2. Using iOS 8's startOfDayForDate (now startOfDay), you don't need to manually set the time to 12pm unless you're doing some really crazy calendar calculations across time zones.

It's worth mentioning that some of the other answers claim you can shortcut this by using Calendar.current.date(byAdding: .month, value: 0, to: Date())!, but where this fails, is that it doesn't actually zero out the day, or account for differences in timezones.

Here you go:

extension Date {    func startOfMonth() -> Date {        return Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!    }        func endOfMonth() -> Date {        return Calendar.current.date(byAdding: DateComponents(month: 1, day: -1), to: self.startOfMonth())!    }}print(Date().startOfMonth())     // "2018-02-01 08:00:00 +0000\n"print(Date().endOfMonth())       // "2018-02-28 08:00:00 +0000\n"


You get the first day of the month simply with

let components = calendar.components([.Year, .Month], fromDate: date)let startOfMonth = calendar.dateFromComponents(components)!print(dateFormatter.stringFromDate(startOfMonth)) // 2015-11-01

To get the last day of the month, add one month and subtract one day:

let comps2 = NSDateComponents()comps2.month = 1comps2.day = -1let endOfMonth = calendar.dateByAddingComponents(comps2, toDate: startOfMonth, options: [])!print(dateFormatter.stringFromDate(endOfMonth)) // 2015-11-30

Alternatively, use the rangeOfUnit method which gives youthe start and the length of the month:

var startOfMonth : NSDate?var lengthOfMonth : NSTimeInterval = 0calendar.rangeOfUnit(.Month, startDate: &startOfMonth, interval: &lengthOfMonth, forDate: date)

For a date on the last day of month, add the length of the month minus one second:

let endOfMonth = startOfMonth!.dateByAddingTimeInterval(lengthOfMonth - 1)

Updated for Swift5:

extension Date {    var startOfDay: Date {        return Calendar.current.startOfDay(for: self)    }    var startOfMonth: Date {        let calendar = Calendar(identifier: .gregorian)        let components = calendar.dateComponents([.year, .month], from: self)        return  calendar.date(from: components)!    }    var endOfDay: Date {        var components = DateComponents()        components.day = 1        components.second = -1        return Calendar.current.date(byAdding: components, to: startOfDay)!    }    var endOfMonth: Date {        var components = DateComponents()        components.month = 1        components.second = -1        return Calendar(identifier: .gregorian).date(byAdding: components, to: startOfMonth)!    }    func isMonday() -> Bool {        let calendar = Calendar(identifier: .gregorian)        let components = calendar.dateComponents([.weekday], from: self)        return components.weekday == 2    }}


With Swift 3 & iOS 10 the easiest way I found to do this is Calendar's dateInterval(of:for:):

guard let interval = calendar.dateInterval(of: .month, for: Date()) else { return }

You can then use interval.start and interval.end to get the dates you need.