nathanreyes
nathanreyes

Reputation: 65

Can I get the localized strings for Day, Week, Month, Year in iOS?

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

Answers (4)

Rouger
Rouger

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

ChikabuZ
ChikabuZ

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

AlexWien
AlexWien

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

HackyStack
HackyStack

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

Related Questions