import Foundation protocol DateItem { var startDate: Date { get } var hasEndDate: Bool { get } var endDate: Date { get } } extension DateItem { private func datePrefixString(in language: ContentLanguage) -> String { guard Calendar.current.isDate(startDate, equalTo: endDate, toGranularity: .year) else { // Different year, return full string return startDate.formatted(date: .long, time: .omitted) } guard Calendar.current.isDate(startDate, equalTo: endDate, toGranularity: .month) else { // Different month return DateItemStorage.dayAndMonth(of: startDate, in: language) } return DateItemStorage.day.string(from: startDate) } func dateText(in language: ContentLanguage) -> String { guard hasEndDate else { return DateItemStorage.dateString(for: startDate, in: language) } let endText = DateItemStorage.dateString(for: endDate, in: language) return "\(datePrefixString(in: language)) - \(endText)" } } private enum DateItemStorage { static let englishDate: DateFormatter = { let df = DateFormatter() df.locale = .init(identifier: "en") df.dateFormat = "d. MMMM yyyy" return df }() static let germanDate: DateFormatter = { let df = DateFormatter() df.locale = .init(identifier: "de") df.dateFormat = "d. MMMM yyyy" return df }() static let englishDayAndMonth: DateFormatter = { let df = DateFormatter() df.locale = .init(identifier: "en") df.dateFormat = "d. MMMM" return df }() static let germanDayAndMonth: DateFormatter = { let df = DateFormatter() df.locale = .init(identifier: "de") df.dateFormat = "d. MMMM" return df }() static let day: DateFormatter = { let df = DateFormatter() df.dateFormat = "d." return df }() static func dayAndMonth(of date: Date, in language: ContentLanguage) -> String { switch language { case .english: return englishDayAndMonth.string(from: date) case .german: return germanDayAndMonth.string(from: date) } } static func dateString(for date: Date, in language: ContentLanguage) -> String { switch language { case .english: return englishDate.string(from: date) case .german: return germanDate.string(from: date) } } }