Home > Enterprise >  Calendar.current.component(.year, from: Date()) returns 4 instead of 2022
Calendar.current.component(.year, from: Date()) returns 4 instead of 2022

Time:07-12

We have a page on our app in which the user can selected a year from a list. The list contains all years from 1900 to 2022. Some users have reported that they don't see the list at all. We couldn't figure out how this happened, so we added a non-fatal issue report that is sent to Crashlytics whenever the initial conditions for displaying the list aren't met.

This is the relevant code:

private lazy var currentYear: Int = {
    Calendar.current.component(.year, from: Date())
}()

private lazy var yearsArray: [String] = {
    if currentYear < 1900 {
        assertionFailure()
        NSError(domain: "OTP_YEAR", code: 1, userInfo: [NSLocalizedDescriptionKey: "CurrentYear < 1900. value: \(currentYear), Date: \(Date())"])
            .reportToExternalServices()
        return []
    }
    let result = (1900 ... currentYear).map { String($0) }
    if result.isEmpty {
        assertionFailure()
        NSError(domain: "OTP_YEAR", code: 2, userInfo: [NSLocalizedDescriptionKey: "Empty years array. currentYear: \(currentYear), Date: \(Date())"])
            .reportToExternalServices()
    }
    if result.contains(where: { $0.trimWhiteSpacesAndNewLine().isEmpty }) {
        assertionFailure()
        NSError(domain: "OTP_YEAR", code: 3, userInfo: [NSLocalizedDescriptionKey: "Years array contains empty strings. currentYear: \(currentYear), Date: \(Date()), Array: \(result)"])
            .reportToExternalServices()
    }
    return result
}()

After a few weeks it happened again and this time we could see the following event reported:

nserror-code: 1
nserror-domain: OTP_YEAR
NSLocalizedDescription: CurrentYear < 1900. value: 4, Date: 2022-07-11 12:59:00  0000

This happened to two of our users, both with iPhone 13 and iOS 15.5

According to the logs, if I understand them correctly, the standard documented way of extracting the year component, Calendar.current.component(.year, from: Date()), returns 4 instead of the current year.

We can't reproduce this situation on our test devices. Any idea why this happens to some of the users?

CodePudding user response:

.current may give unexpected results if the device is set the a different calendar. Use Calendar(identifier: .gregorian) like this :

Calendar(identifier: .gregorian).component(.year, from: Date())
  • Related