Thanks a lot for posting that code – I see exactly what you mean.
I'm now thinking the best thing to do is to stick with DateFormatter after all and use df.setLocalizedDateFormatFromTemplate("jjmm") since that respects the 12/24h system setting, and get rid of my local in-app isTwentyFourHour Bool setting. Then I can use DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: self)?.contains("a") to determine the system setting wherever it's required. Unless there are any other pitfalls you might know about?
I noticed that when using the new date.formatted() API that the output does not respect the 12/24h system setting at all, which is not going to work well for my app. For example, if I set the device region to United States, it always provides a 12h format even when the [Settings > General > Date & Time > 24-Hour Time] system setting is turned on.
Post
Replies
Boosts
Views
Activity
Hi – here's my previous comments rewritten:
Thanks for getting back to me. So, let me try to explain what "it" is again. In a nutshell, I want to use the new date formatting API to display hours and minutes, but I want to control whether the hours are displayed in 12h format or 24h format. This can be done with DateFormatter but I'm currently trying to update some code: I want to replace all the DateFormatter usage with the new API. As an example, I have code using the new API such as date.formatted(formatStyle.hour(.defaultDigits(amPM: .abbreviated)).minute()) where formatStyle is something like in my original question and date is just a date instance.
However, I see no way to control whether the hour digits are provided as 12h or 24h format – they, understandably, come as what is relevant to the user locale by default. So, for example, a user in the US will see 12h digits, and a user in France will see 24h digits. But what I really want to do is respect a local user setting: I have a boolean toggle in my app that allows the user to select their preference (12h vs 24h clocks); if the user has selected that they prefer the 24h format, I want to force the new API to always give me 24h format, and similarly if the user selects the 12h format, I want the new API to always provide the 12h format, no matter what the device locale is. But I so far cannot find a way to do this.
Or, another way of putting it, let's look at the DateFormatter equivalent and see if this can be done with the new API: If we have a local user preference called isTwentyFourHourClock (a Bool) and I wanted to respect that setting I could use formatter.setLocalizedDateFormatFromTemplate(isTwentyFourHourClock ? "HHmm" : "hhmm"). Is there any way to achieve this with the date.formatted() method?
To answer your other questions:
You’re displaying a time to the user? Yes.
You’re trying to display 24-hour time regardless of the user’s preferences? I'm trying to respect the user's local in-app preference for 12h vs 24h formats.
Do you absolutely require a two digit hour? Or do you want the width of any hours before 10 to vary by locale? I actually have a lot of different widgets in my app that display the current time. In some cases I display hours that are zero padded and some that are not necessarily padded. With the new API I see this can be done using .hour(.twoDigits(amPM: .abbreviated)) vs .hour(.defaultDigits(amPM: .abbreviated)).
In the 12-hour case, do you want the am/pm markers? Similarly for the am/pm markers, in some cases I show them, in others they are hidden. This is easily controlled with the Date.FormatStyle.Symbol.Hour.AMPMStyle options.