Reputation: 10116
I use a DateComponentsFormatter
to get a String
to display a TimeInterval
. In this particular case I want to show only minutes and hours (if an hour or greater).
But if I use the same instance of DateComponentsFormatter
(trying to prevent repetitive re-initialization, using a lazy var) and first call the method with a duration greater than or equal to an hour, the second time if it's called with a value less than 10 minutes it always has a leading zero.
class DurationStringHelper {
private lazy var timeFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.zeroFormattingBehavior = .dropLeading
formatter.allowedUnits = [.hour, .minute]
return formatter
}()
public func duration(seconds: TimeInterval) -> String {
return timeFormatter.string(from: seconds)!
}
}
// CASE 1:
let c1 = DurationStringHelper()
c1.duration(seconds: 3600) // "1:00"
c1.duration(seconds: 60) // "01" ARGH WHY GOD WHY!!!
// CASE 2: (first call less than an hour)
let c2 = DurationStringHelper()
c2.duration(seconds: 3599) // "59"
c2.duration(seconds: 60) // "1"
My current approach is just to check if there's an unwanted leading zero (checking for the presence of the character and checking whether the seconds falls into a certain range) and removing it. This is an ugly hack though.
This seems like a bug to me, so I submitted a report to Apple. Don't see why one call to a formatter should affect later calls.
Note: the same thing doesn't seem to happen if you include .day
in allowed units, and first call it with a time interval of a day or more, and then again with less than 10 hours. Although it does happen if you set allowedUnits
to [.minute, .second]
and then call it first with 60 seconds and then with 9 seconds.
Upvotes: 1
Views: 1073