tech_human
tech_human

Reputation: 7100

Issue with determining if time format is 12 hours or 24 hours

In my AppDelegate's applicationWillEnterForeground(_), I have the below code to determine if the device is set to 12 hour or 24 hour time format.

func applicationWillEnterForeground(_ application: UIApplication) {

    let formatter:String? = DateFormatter.dateFormat(fromTemplate:"j", options: 0, locale: NSLocale.current)
    if ((formatter as NSString?)?.range(of: "a"))?.location == NSNotFound {
        Utils.isDeviceFormat24Hours = true
    } else {
        Utils.isDeviceFormat24Hours = false
    }
}

Something that I noticed recently is say my device set to 12 hour time format and I am seeing the time in 12 hour format in my app too. Now I go and change the format to 24 hour and when I come back to the app, the above code gets executed, but formatter value still is "h a" instead of "HH", hence the property "isDeviceFormat24Hours" does not get set to true. But within the date time picker that I use in my app, I do see time in 24 hours format. Now if I put the app again to background and then come back to foreground, that's then I get 'formatter' value as 'HH'.

I played with time formatter settings multiple times and each time I noticed I had to bring my app to foreground twice to reflect the change i.e. for 'formatter' to get set to right time format value.

Anyone else noticing the same? Any idea why this could be happening? I am using iOS 14.7.1 if that matters.

Upvotes: 0

Views: 373

Answers (1)

Leo Dabus
Leo Dabus

Reputation: 236350

The issue there is that your method is getting called before the app enters foreground therefore the method is getting called before the app gets a change to update the current locale settings. What you need is to use didBecomeActive method instead. You can also simplify your code extending Locale as follow:


extension Locale {
    var is24Hour: Bool { DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: self)?.contains("a") == false }
}

Usage:

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if #available(iOS 13.0, *) {
            NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIScene.didActivateNotification, object: nil)
        } else {
            NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
        }
    }
    @objc func didBecomeActive(_ notification: Notification) {
        if Locale.autoupdatingCurrent.is24Hour {
            print("24-Hour Time is ON")
        } else {
            print("24-Hour Time is OFF")
        }
    }
}

Upvotes: 1

Related Questions