Reputation: 65
It doesn't seem to be possible besides doing the manual lookup.
Note that I'm not asking for the localized date. I'd like the actual terms for "day", "week", "month", "year".
Edit: I'm looking for the localized translation. For example, if I calculate 3 months between two dates, I would like to display a localized version of "3 months" to the user. Hope that helps.
Upvotes: 6
Views: 2275
Reputation: 641
You can actually achieve that with DateComponentsFormatter.localizedString(from: to:)
. Here are the docs.
And here's a handy Calendar
extension:
extension Calendar {
func period(unit component: Component, value: Int) -> String? {
let present = Date()
guard let future = date(byAdding: component, value: value, to: present) else { return nil }
let period = dateComponents([component], from: present, to: future)
return DateComponentsFormatter.localizedString(from: period, unitsStyle: .full)
}
}
// Usage:
Calendar.current.period(unit: .month, value: 3) // "3 months"
Also, I wrote this medium article a while ago about relative dates, check it out!
You could do this with only one line:
DateComponentsFormatter.localizedString(from: 3.months, unitsStyle: .full) // "3 months"
Upvotes: 1
Reputation: 10185
We can extract it from DateComponentsFormatter
, here is my Calendar extension:
extension Calendar {
mutating func localizedUnitTitle(_ 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 formatter = DateComponentsFormatter()
if locale != nil {
self.locale = locale
}
formatter.calendar = self
formatter.allowedUnits = [unit]
formatter.unitsStyle = .full
guard let string = formatter.string(from: date, to: sinceUnits) 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
}
}
Usage:
var calendar = Calendar.current
let dayString = calendar.localizedUnitTitle(.day) //Day
let weekString = calendar.localizedUnitTitle(.weekOfMonth) //Week
let monthString = calendar.localizedUnitTitle(.month) //Month
let yearString = calendar.localizedUnitTitle(.year) //Year
let locale = Locale(identifier: "uk")
let secondString = calendar.localizedUnitTitle(.second, locale: locale) //Секунда
Upvotes: 6
Reputation: 28727
There is no built in function that delivers you the localized translation for the english words "day", "week", etc.
You have to use
NSLocalizedString(@"day","");
and provide the language String resources.
Upvotes: 0
Reputation: 5157
Do something like this to get the days of week in locale:
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale: [NSLocale currentLocale]];
NSArray * weekdays = [dateFormatter weekdaySymbols];
If you want the actual words "day", "week", "month" I think you'll have to use NSLocalizedString.
Upvotes: 1