Another solution is to convert the month/day date to the current calendar and compare from there:
let actualBirthDate = Date(year: 2000, month: 2, day: 29)
// Created 'currentDate' as a non-leap year for testing,
// but you would want to use 'Date()' here for your app
let currentDate = Date(year: 2001, month: 3, day: 1)
var birthDateComponents = Calendar.current.dateComponents([.year, .month, .day], from: actualBirthDate)
let currentDateComponents = Calendar.current.dateComponents([.year, .month, .day], from: currentDate)
// Plot the birthdate on this year's calendar.
// Feb.29 will convert to Mar.1 on a non-leap year.
birthDateComponents.year = currentDateComponents.year
if let birthday = Calendar.current.date(from: birthDateComponents) {
var birthdayComponents = Calendar.current.dateComponents([.year, .month, .day], from: birthday)
// Now if day and month match, we know it's your birthday
if birthdayComponents.month == currentDateComponents.month && birthdayComponents.day == currentDateComponents.day {
print("Happy birthday!")
}
}
Modify currentDate
to try out different years (or just set that to Date()
when you're done). February 29 will convert to March 1 on non-leap years, but remain the same on leap years.
If you're wondering about that Date initializer I used, I just have a Date extension that looks like this:
extension Date {
init(year: Int? = nil, month: Int? = nil, day: Int? = nil, hour: Int? = nil, minute: Int? = nil, second: Int? = nil, millisecond: Int? = nil, timeZone: TimeZone? = nil) {
let now = Date()
var dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second, .nanosecond], from: now)
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
dateComponents.hour = hour
dateComponents.minute = minute
dateComponents.second = second
dateComponents.nanosecond = 1000000 * (millisecond ?? 0)
if let timeZone = timeZone {
dateComponents.timeZone = timeZone
}
guard let date = Calendar.current.date(from: dateComponents) else {
fatalError("Failed to construct date")
}
self.init(timeInterval: 0, since: date)
}
}