Is there an existing Objective-C library for dealing with human readability of object counts, file sizes, dates, time durations and so on? (and based on Cocoa's Foundation framework?)
In other words, given an NSDate, NSNumber, NSTimeInterval etc. or an NSArray of objects; is there a library for constructing a string representation that deals with such issues as:
- Counting singular vs. plural: displaying "2 files", "3 files" etc. but "1 file" instead of "1 files".
- Dates: displaying "yesterday" instead of "2010-02-18", "last Monday" instead of "2010-02-15" and so on.
- Durations: displaying "estimated time remaining: about an hour" instead of "...: 57 minutes".
- File sizes: displaying "50 bytes" for 50 bytes, but "1.0 GiB" for 1073741824 bytes and so on.
This seems like such a common issue a library is bound to exist already; perhaps even already a standard framework provided by Apple (though I can't immediately find anything about it). Question is where? ;)
Note: This is really a comment on dreamlax's answer, but it was too long to post as a comment.
Thanks for the link to the MDC article. I do realize this can be a fairly complex issue; even when just considering English, let alone multiple languages.
Then again, the fact that this is such a complex issue is all the more reason why I'd like to have a library that solves some of the issues. ;)
File sizes do seem the most straightforward but even this is easy to get wrong. Consider the following output by code given as answers to similar questions on this site. The first code strangely reports 1023 bytes as 1.0 KB. The second reports (1024 * 1024) - 1 bytes as 1024.00 KB, whereas the first reports it as 1.0 MB. According to Calculator.app, (1024 * 1024) - 1 bytes is about 1.023,9990234375 KB. So should that be displayed as "1023,99 KB", "1024,00 KB", "1.0 MB", ... ? I'm not sure.
I quickly wrote some code earlier today for converting file sizes, and then realized it has similar issues when I wrote unit tests for it.
Would really be nice to have a library in which this has already been thought through ...
1022 bytes = 1022 bytes
1023 bytes = 1.0 KB
1024 bytes = 1.0 KB
1025 bytes = 1.0 KB
(1024 * 1024) - 1 bytes = 1.0 MB
(1024 * 1024) bytes = 1.0 MB
(1024 * 1024) + 1 bytes = 1.0 MB
[ Output with code from ObjC/Cocoa class for converting size to human-readable string? ]
1022 bytes = 1022.00 B
1023 bytes = 1023.00 B
1024 bytes = 1024.00 B
1025 bytes = 1.00 KB
(1024 * 1024) - 1 bytes = 1024.00 KB
(1024 * 1024) bytes = 1024.00 KB
(1024 * 1024) + 1 bytes = 1.00 MB
[ Output with code from File size in Snow Leopard ]
Code to produce the above output (fairly obvious, but just for reference):
NSLog(@"1022 bytes = %@", [self asFileSizeString: [NSNumber numberWithInt: 1022]]);
NSLog(@"1023 bytes = %@", [self asFileSizeString: [NSNumber numberWithInt: 1023]]);
NSLog(@"1024 bytes = %@", [self asFileSizeString: [NSNumber numberWithInt: 1024]]);
NSLog(@"1025 bytes = %@", [self asFileSizeString: [NSNumber numberWithInt: 1025]]);
NSLog(@"(1024 * 1024) - 1 bytes = %@", [self asFileSizeString: [NSNumber numberWithInt: (1024 * 1024) - 1]]);
NSLog(@"(1024 * 1024) bytes = %@", [self asFileSizeString: [NSNumber numberWithInt: (1024 * 1024)]]);
NSLog(@"(1024 * 1024) + 1 bytes = %@", [self asFileSizeString: [NSNumber numberWithInt: (1024 * 1024) + 1]]);