I have just created a playground to test this code out. It seems to work properly for the dates I have provided.
See what you think and whether it works in your project.
let calendar = Calendar.current
// Manual creation of dates so you can see what the values for each are
let components = [
DateComponents(year: 2004, month: 3, day: 26),
DateComponents(year: 1973, month: 7, day: 4),
DateComponents(year: 1992, month: 4, day: 1),
DateComponents(year: 2012, month: 12, day: 23),
DateComponents(year: 1988, month: 9, day: 16)
]
let birthdays = components.compactMap(calendar.date)
// You would only need this bit in your project
let nextBirthdays = birthdays.compactMap {
let components = calendar.dateComponents([.day, .month], from: $0)
return calendar.nextDate(after: .now, matching: components, matchingPolicy: .nextTime)
}.sorted(by: <)
let nextBirthday = nextBirthdays.first
print(nextBirthday) // Optional(2022-12-23 00:00:00 +0000)
This part is what you would put in your project:
// Wrap up next birthday calculation inside a function
func nextBirthday(for birthday: Date) -> Date {
let calendar = Calendar.current
let components = calendar.dateComponents([.day, .month], from: birthday)
return calendar.nextDate(after: .now, matching: components, matchingPolicy: .nextTime) ?? .distantFuture
}
// Sorted friends by next birthday first
friends.sorted {
nextBirthday(for: $0.bday) < nextBirthday(for: $1.bday)
}