If your iOS device is set to use a region that defaults to 12 hour time (e.g. United States) and you have a DateFormatter
set up like this:
var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "h:mm a"
return formatter
}()
Then it will output the time in a 24 hour format if the "24-Hour Time" switch is turned ON in Date & Time in Settings in iOS.
If your custom date format is "H:mm", i.e. 24 hour, and you're still in a default-12h region, then it will output 24 hour time regardless of the on/off state of the 24 hour switch.
Ok, so fine, simple, I'll just use "h:mm a" and then users will see whatever time displayed according to the format they prefer. BUT if you change your region to a region that uses 24 hour time by default, then the behaviour is reversed! If you have "H:mm" and the 24-hour time switch is OFF it will change it to 12 hour time ("h:mm a").
Yes, you can usually avoid this by using the time style (formatter.timeStyle = .short
, for example) instead of using custom date formats, but what are you supposed to do if you need a custom date format and you want to respect a user's settings? (For example, if you need to insert some custom characters in the string or just want to have the components in a non-standard order)
I suppose the only way to have your cake and eat it too here is to check in advance what the user's preference is (which you can't really do directly, as far as I can tell) or maybe what the locale's default is (I don't see any way to do that though) and then adjust the format accordingly…
I made this Xcode project to demonstrate the issue more clearly (obviously it must be run on a device as there is no 24 hour time switch on the simulator).
I am aware there are various workarounds, but I don't understand what Apple expects you to do if you're making an app that uses custom date/time formats for your UI and has users from different regions in the world? Am I missing something or is this a flaw in iOS?
Note: This question is specifically about converting dates to strings for display purposes, so I want to respect the user's locale and other settings whenever possible. I am aware you can set the locale to en_POSIX etc. but that doesn't solve the problem. I also would prefer to make this as seamless as possible and take advantage of whatever is built in, but that doesn't seem to be possible here unless you only target users in regions that have the same default 24 hour time settings…
See Question&Answers more detail:
os