What am I doing wrong with NSDateComponentsFormatt

2019-01-29 12:39发布

问题:

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.)

回答1:

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"