I recently found out about the new-to-iOS8 class NSDateComponentsFormatter, which lets you format time intervals rather than dates. Cool. I've written code to do this more times than I care to think about. So I decided to try and use it in a playground, but I can't get it to work. Here's my (Swift) code:
var componentsFormatter = NSDateComponentsFormatter()
componentsFormatter.allowedUnits =
.CalendarUnitHour |
.CalendarUnitMinute |
.CalendarUnitSecond
componentsFormatter.unitsStyle = .Positional
let interval: NSTimeInterval = 345.7
let intervalstring = componentsFormatter.stringFromTimeInterval(interval)
println("Interval as String = \(intervalstring)")
This displays
Interval as String = nil
I've tried various things, but no joy. Does anybody have a working example using this new class, or can you spot what I'm missing?
(I speak Objective-C too, so if you have sample code in Objective-C that works as well.)
Swift 3.1 • Xcode 8.3.2
extension Formatter {
static let dateComponents: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.unitsStyle = .full
formatter.includesApproximationPhrase = true
formatter.includesTimeRemainingPhrase = true
formatter.maximumUnitCount = 2
formatter.zeroFormattingBehavior = .default
formatter.allowsFractionalUnits = false
formatter.allowedUnits = [.year, .month, .weekOfMonth, .day, .hour, .minute, .second]
return formatter
}()
}
extension TimeInterval {
var remainingTime: String {
return Formatter.dateComponents.string(from: self) ?? ""
}
}
let interval = 60.0 * 60 * 24 * 7
let intervalstring = interval.remainingTime // "About 1 week remaining"
Positional Time
extension Formatter {
static let positional: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
formatter.zeroFormattingBehavior = .default
formatter.allowedUnits = [.hour, .minute, .second]
return formatter
}()
}
extension TimeInterval {
var hourMinuteSecond: String {
return Formatter.positional.string(from: self) ?? ""
}
}
let time = 345.7
let positional = time.hourMinuteSecond // "5:45"