1

I have 24-Hour Time switch ON on the device and testing the iOS App for different timezones which gives me the correct time format.

Ex:

  • 23:00 PDT if 24-Hour Time switch ON
  • 11 PM PDT if 24-Hour Time switch OFF

But, if I change my region in the device to Japan or France for any timezone. I observe the time format is ignoring the 24-Hour Time switch and always showing the 12-hour format. Whereas, if the region is set to the United States or India I see correct results.

func formattedCloseTime(for date: DateTimeZone) -> String {
    let formatter = dateProvider.formatter
    formatter.timeZone = date.timeZone
    formatter.locale = .autoupdatingCurrent

    let stopTimeMinutes = dateProvider.minutesOfDay(from: date.value, timeZone: date.timeZone)
//    formatter.dateFormat = stopTimeMinutes == 0
//      ? Constants.DateFormat.hourFormat
//      : Constants.DateFormat.hourMinuteFormat
    formatter.setLocalizedDateFormatFromTemplate(stopTimeMinutes == 0
                                                 ? Constants.DateFormat.hourFormat
                                                 : Constants.DateFormat.hourMinuteFormat)
    return formatter.string(from: date.value)
  }

I'm surprised why is it happening only in a few regions. Is there any relation between region and time format? How do I solve this case?

NOTE: I don't want to firm the time format to 24 hours only. I want it to take the user's device settings.

Solution Apple API of setLocalizedDateFormatFromTemplate doesn't look like working correctly for all regions. So, I considered taking the user's settings of the 24-hour switch value and displaying the format accordingly. You can check out this to get the user's settings 24-hour value.

var isTwentyFourHourTimeSet: Bool {
      let formatString = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)!
      return !formatString.contains("a")
  }

3 Answers3

1

I have a similar issue. My way of detecting whether time should use AM/PM is similar to your approach:

let formatter = DateFormatter()
formatter.locale = Locale.current
formatter.dateStyle = .none
formatter.timeStyle = .short
let stringDate = formatter.string(from: Date())
let amPM = stringDate.contains(formatter.amSymbol) || 
    stringDate.contains(formatter.pmSymbol)

But both of our solutions stop working when the language is French and the region is Canada: DateFormatter uses AM/PM.

This appears to be expected behavior per Locale.current reporting wrong language on device. Apple wants consistent date/number/etc. formatting to developer fallback if no localization it seems.

language and region settings screen shot

t9mike
  • 1,546
  • 2
  • 19
  • 31
0

You can lock the date format in 24 hrs by declaring

formatter.dateFormat = "HH:mm"
Abdul Karim Khan
  • 4,256
  • 1
  • 26
  • 30
  • But, I don't want to lock the time format to 24 hours only. I want it to take the user's device settings and show them accordingly. Is this bug something unsolvable without locking it to 24-hour format completely? – tejasree vangapalli Oct 28 '21 at 15:27
  • What you have done is correct but if you are facing challenge when changing timezone, you can declare time format like above so that it stays in 24 hr. I hope it helped. – Abdul Karim Khan Oct 28 '21 at 15:58
  • I'm not facing any challenge when the timezone is changed. I mentioned I get wrong results when the region is changed @abdul – tejasree vangapalli Oct 28 '21 at 16:53
  • @Txv428 Did you add the above code? Are you still getting wrong result after adding this line? – Abdul Karim Khan Oct 28 '21 at 16:55
  • apple API doesn't look like working correctly in all regions. So, I'm trying to get the user's 24-hour switch value from settings and show the format accordingly. – tejasree vangapalli Dec 14 '21 at 17:29
0

You can try out by using this code to get 24 hour time formate

func changeTimeFormate() {
    let dateString = "11:00 PM"
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "h:mm a"
    dateFormatter.locale = Locale(identifier: "en_US_POSIX") // fixes nil if device time in 24 hour format
    let date = dateFormatter.date(from: dateString)

    dateFormatter.dateFormat = "HH:mm"
    let date24 = dateFormatter.string(from: date ?? Date())
    print(date24)

}
Rushita
  • 11
  • 4
  • 1
    But, I don't want to lock the time format to 24 hours only. I want it to take the user's device settings and show them accordingly. Is this bug something unsolvable without locking it to 24-hour format completely? – tejasree vangapalli Oct 28 '21 at 15:26