This is absolutely a bug in Foundation
. The documentation and examples both say that the leading "0" shouldn't be included.
Until the bug is fixes, the solutions available would be to either do string manipulation or to use a different format style. Each one has their own drawbacks when it comes to internationalization, so deciding which solution to use is a matter of weighing your needs against the drawbacks.
Simply check for the existence of a leading 0
character, and remove it if needed.
// https://www.hackingwithswift.com/example-code/strings/how-to-remove-a-prefix-from-a-string
extension String {
func deletingPrefix(_ prefix: String) -> String {
guard self.hasPrefix(prefix) else { return self }
return String(self.dropFirst(prefix.count))
}
}
let testDate = try! Date("2024-01-01T10:36:01Z", strategy: .iso8601)
let dateString = testDate.formatted(.dateTime.hour(.defaultDigits(amPM: .omitted)).minute()) // 03:36
dateString.deletingPrefix("0") // 3:36
This would only work for locales that use Arabic numerals of course. If you're relying on strict internationalization then you would need to be a bit more clever in detecting leading characters.
This would let you build out a fully custom date string, but at the cost of having the hour minute separator be hardcoded to be a colon character.
let testDate = try! Date("2024-01-01T10:36:01Z", strategy: .iso8601)
let hourMinuteStyle = Date.VerbatimFormatStyle(
format: "\(hour: .defaultDigits(clock: .twelveHour, hourCycle: .zeroBased)):\(minute: .defaultDigits)",
timeZone: .autoupdatingCurrent,
calendar: .autoupdatingCurrent
)
testDate.formatted(hourMinuteStyle) // 3:36
// OR
testDate.formatted(
.verbatim(
"\(hour: .defaultDigits(clock: .twelveHour, hourCycle: .zeroBased)):\(minute: .defaultDigits)",
timeZone: .autoupdatingCurrent,
calendar: .autoupdatingCurrent
)
)