first and last day of the current month in swift

user2363025 picture user2363025 · Nov 9, 2015 · Viewed 59.2k times · Source

I'm trying to get the first and last day of the month in swift.

So far I have the following:

let dateFormatter = NSDateFormatter()
let date = NSDate()
dateFormatter.dateFormat = "yyyy-MM-dd"
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: date)

let month = components.month
let year = components.year

let startOfMonth = ("\(year)-\(month)-01")

But I'm not sure how to get the last date. Is there a built in method I'm missing? Obviously it has to take into account leap years etc.

Answer

brandonscript picture brandonscript · Jan 26, 2016

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"