Reputation: 11305
I'm building a calendar view that I want to be agnostic of the year, just list all the possible dates that can occur in a month. I.e. to show the maximum number of days in a calendar, like February 29th. From this answer, I know there are other calendar systems that also have leap days, so I'm curious how I might be able to tell if a calendar has a leap day, regardless of the calendar system or year. Any help would be greatly appreciated! Here is what I have currently to get the number of days in a month:
func days(in month: Int) -> Int {
let components = DateComponents(month: month+1, day: -1)
let lastDay = Calendar.current.date(from: components)!
return Calendar.current.dateComponents([.day], from: lastDay).day!+1
}
This works great, but is based on the current year, which may not be a leap year.
I've seen isLeapMonth
but this doesn't seem to work to query in the same way as .day
.
Upvotes: 3
Views: 2002
Reputation: 236420
edit/update:
You can get the next leap year for the current calendar and check the maximum number of days in month, maybe something like this:
extension Date {
var year: Int { Calendar.current.component(.year, from: self) }
var isLeapYear: Bool { Calendar.current.range(of: .day, in: .year, for: self)!.count == 366 }
// find the leap year
static var leapYear: Int {
var year = Date().year
while DateComponents(calendar: .current, year: year).date?.isLeapYear == false {
year += 1
}
return year
}
}
Date.leapYear // 2020
func maximumNumberOfDays(in month: Int) -> Int? {
Calendar.current.range(of: .day,
in: .month,
for: DateComponents(calendar: .current,
year: Date.leapYear,
month: month).date!)?.count
}
maximumNumberOfDays(in: 2) // 29
Upvotes: 3