问题 NSDateComponentsFormatter stringFromTimeInterval为短于1分钟的间隔返回不正确的字符串


我在iOS 8上使用NSDateComponentsFormatter,我注意到在实现中可能存在错误 stringFromTimeInterval: 方法,但我不能肯定地说。

这就是我设置格式化程序的方法:

NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDefault;
formatter.allowedUnits = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
formatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;

现在,当我通过不到60秒的任何东西时 stringFromTimeInterval: 方法,格式化程序返回 1 要么 01,这显然是错误的,它应该返回类似的东西 0:XX

我还注意到,通过改变 unitsStyle 除了 NSDateComponentsFormatterUnitsStylePositional 该方法返回一个正确的字符串!

例:

unitsStyle = NSDateComponentsFormatterUnitsStylePositional

(lldb) po [formatter stringFromTimeInterval:12]
= "1"

=>应该返回“0:12”!!

unitsStyle = NSDateComponentsFormatterUnitsStyleAbbreviated

(lldb) po [formatter stringFromTimeInterval:12]
= "12 s"

=>正确!

这让我觉得它是Apple实现API的一个错误,还是我错过了什么?


12430
2018-01-22 11:32


起源

看看我的回答/解决方案...... - MiKL
我知道这不是解决方案,但是如果它低于60,你可以设置timeInterval中的浮点字符串值:if(self.timeInterval <60){stringFromInterval = [NSString stringWithFormat:@“%2.0f”,self.timeInterval ]。您是否考虑过在Apple开发者论坛中提问? - xarly


答案:


这似乎仍然是iOS 8.3和Xcode 6.3的问题。 有一种方法可以解决它,但是,如果不是完美的话,至少可以让你获得正确的格式,而不必自己处理拆分时间相关的组件。

以下是Swift中的示例变通方法(您可以在Playground中进行测试)

let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Positional
formatter.zeroFormattingBehavior = .Pad
formatter.allowedUnits = .CalendarUnitMinute | .CalendarUnitSecond

调用 let string = formatter.stringFromTimeInterval(4) 将打印“00:04”。

调用 let string = formatter.stringFromTimeInterval(88) 将打印“01:28”。

现在你可以玩了 allowedUnits 取决于您是否有超过1小时或1天。例如,在有一个类的类中 formatter 属性:

func updateTimeFormatterForTime(time: NSTimeInterval) {
   if time > 3600 && time < 24 * 3600 {
      self.formatter.allowedUnits = .CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond
   } else if time > 24 * 3600 {
      self.formatter.allowedUnits = .CalendarUnitDay | .CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond
   }
}

9
2018-04-19 14:29



.CalendarUnitMinute和.CalendarUnitHour,这些在9.1中不再存在我不认为或者他们从未做过或者我不知道在哪里找到它们。由于某种原因,我不能将它们分配给allowedUnits,它们不是NSDateComponentsFormatter的一部分,至少不再是它的一部分。 - Nathan McKaskle
.CalendarUnitMinute 等人现在 .Minute 他们没有被删除。 - squarefrog


NSDateComponentsFormatterZeroFormattingBehaviorDefault表示删除前导零,为Positional单位样式填充其他零。

例如使用代码中的allowedUnits值,[formatter stringFromTimeInterval:120]结果为“2:00”而不是“0d 0:02:00”, 因为formatter对象删除了所有前导零值。

如果要保留零值位置,可以使用NSDateComponentsFormatterZeroFormattingBehaviorNone

为什么[formatter stringFromTimeInterval:12]结果为1,我认为格式化程序对象单独发现“12”是不明确的,因为它没有例如“1d”中的尾随值或含义指示符。


2
2018-01-30 14:36





这个功能怎么样:

func stringFromTimeInterval(interval: NSTimeInterval) -> String {
    let ti: Int = Int(interval)
    let seconds: Int = ti % 60
    let minutes: Int = (ti / 60) % 60
    let hours: Int = (ti / 3600)
    var time: String? = nil
    if hours > 0 {
        time = String(format: "%02i:%02i:%02i", hours, minutes, seconds)
    }
    else {
        time = String(format: "%02i:%02i", minutes, seconds)
    }
    return time!
}

以此格式化字符串返回时间:59:04(mm:ss)或09:01:34(hh:mm:ss)


0
2018-04-24 07:33