I am using the following DateComponentsFormatter in Swift:
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.allowedUnits = [.hour, .minute, .second]
formatter.zeroFormattingBehavior = [.default]
This produces results like 2:41 (for 2 minutes and 41 seconds) and 08 (for 8 seconds). I would, however, like to keep at least one digit in the Minutes place, returning 0:08 instead of 08. Is this possible with the DateComponentsFormatter? I would prefer a solution that returns a localized result.
Yes. This can be easily accomplished adding a ternary conditional based on the time interval when setting the date components formatter allowed units:
Xcode 11 • Swift 5.1
extension Formatter {
static let positional: DateComponentsFormatter = {
let positional = DateComponentsFormatter()
positional.unitsStyle = .positional
positional.zeroFormattingBehavior = .pad
return positional
}()
}
extension TimeInterval {
var positionalTime: String {
Formatter.positional.allowedUnits = self >= 3600 ?
[.hour, .minute, .second] :
[.minute, .second]
let string = Formatter.positional.string(from: self)!
return string.hasPrefix("0") && string.count > 4 ?
.init(string.dropFirst()) : string
}
}
Usage
8.0.positionalTime // "0:08"
161.0.positionalTime // "2:41"
3600.0.positionalTime // "1:00:00"
Came up with this solution, employing a regex, that seemingly covers all cases:
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
formatter.unitsStyle = .positional
formatter.zeroFormattingBehavior = .pad
func durationString(for duration: TimeInterval) -> String {
formatter.string(from: duration)!
.replacingOccurrences(of: #"^00[:.]0?|^0"#, with: "", options: .regularExpression)
}
durationString(for: 0) // 0:00
durationString(for: 1) // 0:01
durationString(for: 10) // 0:10
durationString(for: 60) // 1:00
durationString(for: 600) // 10:00
durationString(for: 3600) // 1:00:00
durationString(for: 36000) // 10:00:00
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With