Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What am I doing wrong with allowsFractionalUnits on NSDateComponentsFormatter?

Basically what I want is to get the value of a time interval represented in hours only, without rounding it to full hours (using NSDateComponentsFormatter to get it properly formatted and localized). I don't know if I misunderstand the use of NSDateComponentsFormatter.allowsFractionalUnits, but I can't get the formatter to give me a decimal value. Can anyone help me spot my error or tell me in what way I misunderstand this?

From Apple docs about allowsFractionalUnits property:

Fractional units may be used when a value cannot be exactly represented using the available units. For example, if minutes are not allowed, the value “1h 30m” could be formatted as “1.5h”.

Swift example code:

let formatter = NSDateComponentsFormatter() formatter.unitsStyle = .Abbreviated formatter.allowedUnits = .Hour formatter.allowsFractionalUnits = true  let onePointFiveHoursInSeconds = NSTimeInterval(1.5 * 60.0 * 60.0) print(formatter.stringFromTimeInterval(onePointFiveHoursInSeconds)!) //"1h" instead of expected "1.5h" 

Same example in Objective-C code:

NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init]; formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleAbbreviated; formatter.allowedUnits = NSCalendarUnitHour; formatter.allowsFractionalUnits = YES;  NSTimeInterval onePointFiveHoursInSeconds = 1.5 * 60.0 * 60.0; NSLog(@"%@", [formatter stringFromTimeInterval:onePointFiveHoursInSeconds]); //"1h" instead of expected "1.5h" 

Update: I have reported a bug to Apple about this problem (rdar://22660145).

like image 543
osanoj Avatar asked Sep 11 '15 11:09

osanoj


1 Answers

According to Open Radar #32024200:

After doing some digging (disassembling Foundation), it looks like every call to -[_unitFormatter stringFromNumber:] in -[NSDateComponentsFormatter _stringFromDateComponents:] is passed an +[NSNumber numberWithInteger:] which drops floating point data.

You're not doing anything wrong. The flag is simply broken.

like image 74
Ssswift Avatar answered Sep 21 '22 01:09

Ssswift