This can be done by using different formatter configurations depending on the distance of the date.
And to make sure the format matches the user's region/preferences, you should not supply your own string to dateFormat
but use setLocalizedDateFormatFromTemplate(_)
. The latter lets you specify the components you want (day of week, day of month, month, etc), and the OS will put them in the right order and add punctuation (e.g. "June 13" would become "13. Juni" in German).
Also, your preferred format in your question doesn't include a year, but to be able to show any date unambiguously, you could check if the year is the current one and display it if it isn't.
This function should do what you want:
func formatDate(_ date: Date) -> String {
let calendar = Calendar.current
let now = Date.now
let startOfToday = calendar.startOfDay(for: now)
let startOfDayOnDate = calendar.startOfDay(for: date)
let formatter = DateFormatter()
let daysFromToday = calendar.dateComponents([.day], from: startOfToday, to: startOfDayOnDate).day!
if abs(daysFromToday) <= 1 {
// Yesterday, today or tomorrow
formatter.dateStyle = .full
formatter.doesRelativeDateFormatting = true
}
else if calendar.component(.year, from: date) == calendar.component(.year, from: now) {
// Another date this year
formatter.setLocalizedDateFormatFromTemplate("EEEEdMMMM")
}
else {
// Another date in another year
formatter.setLocalizedDateFormatFromTemplate("EEEEdMMMMyyyy")
}
return formatter.string(from: date)
}
This test:
let dayBeforeYesterday = Date.now.addingTimeInterval(-48 * 3600)
let distantDate = Date.now.addingTimeInterval(-100_000_000)
print(formatDate(.now))
print(formatDate(dayBeforeYesterday))
print(formatDate(distantDate))
…prints this (on a device with UK locale, thus the day-month-year ordering):
Today
Friday, 15 December
Friday, 16 October 2020
14 Sep 2020
, 1 day ago showsYesterday
, today showsToday
, 1 day in the future showsTomorrow
and 2 days in the future shows18 Sep 2020
- I'd be more focus on you parser – HavanaDate.init(fromString:format:)
? – Hamburg