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

Jon*_*asG 11 cocoa-touch objective-c nsdate nsdatecomponents ios

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

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

NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDefault;
formatter.allowedUnits = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
formatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
Run Code Online (Sandbox Code Playgroud)

现在,当我向stringFromTimeInterval:方法传递少于60秒的任何内容时,格式化程序返回1或者01,这显然是错误的,它应该返回类似的东西0:XX.

我还注意到,通过更改unitsStyle为任何东西,但NSDateComponentsFormatterUnitsStylePositional方法返回正确的字符串!

例:

unitsStyle = NSDateComponentsFormatterUnitsStylePositional:

(lldb) po [formatter stringFromTimeInterval:12]
= "1"
Run Code Online (Sandbox Code Playgroud)

=>应该返回"0:12"!!

unitsStyle = NSDateComponentsFormatterUnitsStyleAbbreviated:

(lldb) po [formatter stringFromTimeInterval:12]
= "12 s"
Run Code Online (Sandbox Code Playgroud)

=>正确!

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

MiK*_*iKL 9

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

以下是Swift中的示例解决方法(您可以在Playground中测试)

let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Positional
formatter.zeroFormattingBehavior = .Pad
formatter.allowedUnits = .CalendarUnitMinute | .CalendarUnitSecond
Run Code Online (Sandbox Code Playgroud)

通话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
   }
}
Run Code Online (Sandbox Code Playgroud)


小智 2

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

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

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

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