0

I have to display date and time in an iOS app based on locale (Region) and time format (24-Hour vs 12-Hour) set in the device Settings app.

I am using below code for the same :-

class func getDateTimeString(_ fromDate: Date?) -> String {
    var dateTimeString = ""
    if let date = fromDate {
        let format = DateFormatter()
        format.timeZone = .current
        format.dateFormat = DateFormatter.dateFormat(fromTemplate: "MMM dd, YYYY hh:mm a", options: 0, locale: Locale.current)
        dateTimeString = format.string(from: date)
    }
    return dateTimeString
}

This works good to display date as per any locale (Region) set in Settings app. Like for India, it displays date as dd-mmm-yyyy. For US - mmm dd, yyyy. For Germany - dd. mmm yyyy

However, as per time format this works good for regions like US, UK, India, Australia but not for France and Germany. As in it displays the time in 12-hour (AM/PM) format or 24-hour format based on what is selected in the Settings app for US, UK, India and Australia but for Germany and France it displays time only in 12-hour format with AM and PM, irrespective of what is set in time format in Settings app.

Is this expected? If yes, why? If no, what am I missing here? I observed one thing though. Changing the Region to US, UK, India, Australia in Settings changes the time format automatically to 12 hour format under Date&Time settings. However, it remains 24-hour format when changing region to Germany or France.

To resolve the 12-hour format issue for regions like Germany and France, I took cues from https://stackoverflow.com/a/49438640/3148811 and had to modify above code to -

class func getDateTimeString(_ fromDate: Date?) -> String {
    var dateTimeString = ""
    if let date = fromDate {
        let format = DateFormatter()
        format.timeZone = .current
        if let dateFormatterString = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current), dateFormatterString.firstIndex(of: "a") != nil {
            format.dateFormat = DateFormatter.dateFormat(fromTemplate: "MMM dd, YYYY hh:mm a", options: 0, locale: Locale.current)
        } else {
            format.dateFormat = DateFormatter.dateFormat(fromTemplate: "MMM dd, YYYY HH:mm", options: 0, locale: Locale.current)
        }
        dateTimeString = format.string(from: date)
    }
    return dateTimeString
}

Is this a good way to resolve the same?

letsbondiway
  • 470
  • 3
  • 18
  • 1
    From the referenced thread I would assume that `fromTemplate: "MMM dd, YYYY j.mm"` does the trick, have you tried that? – Martin R Oct 26 '22 at 14:55
  • 1
    IMO you should reread this page and see the examples: https://developer.apple.com/documentation/foundation/dateformatter. For instance looks to me that you could make a good use of predefined templates, e.g. `dateFormatter.dateStyle = .medium` and let locale take care about specifics of how it's displayed instead of setting the date. – timbre timbre Oct 26 '22 at 15:00
  • @MartinR I had not tried that, tried that out and it works. Thanks. – letsbondiway Oct 26 '22 at 15:20
  • @khjfquantumjj Thanks, I did not know about predefined templates. Replacing the entire dateFormat fromTemplate code and checks with ```dateFormatter.dateStyle = .medium``` and ```dateFormatter.timeStyle = .short``` made the code smaller and it worked too. – letsbondiway Oct 26 '22 at 15:22
  • 1
    If one of the pre-defined formats like `.medium` or `.short` meet your needs you should **definitely** use those. – Duncan C Oct 26 '22 at 15:35

0 Answers0