Finally found the solution by myself with:
extension Calendar {
/// get a calendar configured with the language of the user
static var localized: Calendar {
let prefLanguage = Locale.preferredLanguages[0]
var calendar = Calendar(identifier: .gregorian)
calendar.locale = Locale(identifier: prefLanguage)
return calendar
}
func unitTitle(_ unit: NSCalendar.Unit, value: Int = 1, locale: Locale? = nil) -> String {
let emptyString = String()
let date = Date()
let component = getComponent(from: unit)
guard let sinceUnits = self.date(byAdding: component, value: value, to: date) else {
return emptyString
}
let timeInterval = sinceUnits.timeIntervalSince(date)
let formatter = DateComponentsFormatter()
formatter.calendar = self
formatter.allowedUnits = [unit]
formatter.unitsStyle = .full
guard let string = formatter.string(from: timeInterval) else {
return emptyString
}
return string.replacingOccurrences(of: String(value), with: emptyString).trimmingCharacters(in: .whitespaces).capitalized
}
// swiftlint:disable:next cyclomatic_complexity
private func getComponent(from unit: NSCalendar.Unit) -> Component {
let component: Component
switch unit {
case .era:
component = .era
case .year:
component = .year
case .month:
component = .month
case .day:
component = .day
case .hour:
component = .hour
case .minute:
component = .minute
case .second:
component = .second
case .weekday:
component = .weekday
case .weekdayOrdinal:
component = .weekdayOrdinal
case .quarter:
component = .quarter
case .weekOfMonth:
component = .weekOfMonth
case .weekOfYear:
component = .weekOfYear
case .yearForWeekOfYear:
component = .yearForWeekOfYear
case .nanosecond:
component = .nanosecond
case .calendar:
component = .calendar
case .timeZone:
component = .timeZone
default:
component = .calendar
}
return component
}
}
And the use is:
Calendar.localized.unitTitle(.day)
Calendar.localized.unitTitle(.weekofMonth)
Calendcar.localized.unitTitle(.month)