This article describes how you use number formatters using Mac OS X v10.4 and later and iPhone OS. If you are using Mac OS X v10.3 or earlier, you should read “Date and Number Formatters on Mac OS X v10.0 to 10.3.”
Behavior Modes
Formatter Styles
Parsing and Creating Strings
Format Strings
Percentages
Nomenclature
On Mac OS X desktop version 10.4 and later, instances of an NSDateFormatter
can operate in two modes, 10.0 compatibility mode and 10.4 mode.
iPhone OS: The v10.0 compatibility mode is not available on iPhone OS—only the 10.4 mode is available.
In the v10.0 compatibility mode, NSNumberFormatter
operates as it did in Mac OS X from version 10.0 to 10.3, including the limitations and any outstanding bugs—see “Date and Number Formatters on Mac OS X v10.0 to 10.3.”
On Mac OS X v10.4 and later, the behavior of the NSDateFormatter
class is based on CFDateFormatter, which is in turn based on the open-source ICU (International Components for Unicode) library. (NSDateFormatter
and CFDateFormatter, however, are not toll-free bridged.) The v10.4 behavior mode allows more configurability and better localization.
The v10.4 behavior mode allows more configurability and better localization; you should use it for any new projects, and ideally upgrade any existing code that uses v10.0 behavior to use v10.4 behavior.
For backwards binary compatibility, the default behavior for NSNumberFormatter
in Mac OS X v10.4 is the v10.0 behavior. On Mac OS X version 10.5 and later, however, the default is the v10.4 behavior. You can set the default behavior of all instances of NSNumberFormatter
to the v10.4 behavior by invoking the class method, setDefaultFormatterBehavior:
with the argument NSNumberFormatterBehavior10_4
. You can also set the behavior for any instance individually by invoking setFormatterBehavior:
.
You can set an application default (preference) to cause number formatters to be automatically converted to the new style. Set the NSMakeNumberFormatters10_4
default to a Boolean YES
/true
value in the application's preferences. You must set the preference before any use is made of the NSNumberFormatter
class. Note that the default has two effects:
Number formatters you initialize with init
adopt the v10.4 formatter behavior.
Number formatters that are unarchived from either non-keyed or keyed archives are converted to v10.4-style if the archived formatter has an un-customized format string at unarchive time.
The object type for number formatters that use the v10.0 behavior mode is still NSDecimalNumber
, but for new-style formatters it is NSNumber
. If you want, you can configure a new style formatter to generate instances of NSDecimalNumber
using the method setGeneratesDecimalNumbers:
(with the argument, YES
). You are encouraged, however, to use NSNumber
for new style formatters.
The v10.4 methods do not do anything when invoked on a v10.0-style formatter, and return a generic return value when required to return something. You should not invoke the v10.4 methods on a v10.0-style formatter. On a v10.4-style formatter, the old methods map approximately to one or more new methods/attributes, but the new methods should be used directly when possible.
There are many new attributes you can get and set on a v10.4-style number formatter, including the number style, locale, negative-number and positive-number format strings, strings for special values, text attribute sets for created attributed strings, and various other configuration attributes. You are encouraged, however, not to change individual settings, but instead to use the NSNumberFormatter
style constants to specify pre-defined sets of attributes that determine how a formatted number is displayed—NSNumberFormatterNoStyle
, NSNumberFormatterDecimalStyle
, NSNumberFormatterCurrencyStyle
, NSNumberFormatterPercentStyle
, NSNumberFormatterScientificStyle
, or NSNumberFormatterSpellOutStyle
(which generates a textual representation of a number). These are styles that the user can configure in the International preferences panel in System Preferences. If you specify your own format string, you lose user-configurability.
In addition to the methods inherited from NSFormatter
, NSNumberFormatter
adds two convenience methods—stringFromNumber:
and numberFromString:
—and a new method to parse a string—getObjectValue:forString:range:error:
. These methods make it easier for you to use an NSNumberFormatter
object directly in code, and make it easier to format numbers into strings in more complex and more convenient ways than NSString
formatting allows.
The getObjectValue:forString:range:error:
method allows you to specify a subrange of the string to be parsed, and it returns the range of the string that was actually parsed (in the case of failure, it indicates where the failure occurred). It also returns an NSError
object that can contain richer information than the failure string returned by the getObjectValue:forString:errorDescription:
method inherited from NSFormatter
.
Note that, since they work with general instances of NSFormatter
, instances of NSCell
only invoke the NSFormatter
getObjectValue:forString:errorDescription:
method in Mac OS X v10.4. For a v10.4-style number formatter, that method calls getObjectValue:forString:range:error:
.
The new methods in v10.4 do not do anything when invoked on a v10.0-style formatter, and return a generic return value when required to return something. The new methods should not be invoked on a v10.0-style formatter. On a v10.4-style formatter, the old methods map approximately to one or more new methods/attributes, but the new methods should be used directly when possible.
The format string uses the format patterns from the Unicode Technical Standard #35 (this reference is to version tr35-6; formatters for Mac OS X v10.4 use version tr35-4). (When the formatter is in v10.0 mode, you must use the old-style format strings, described in “Number Format String Syntax (Mac OS X Versions 10.0 to 10.3).”) Note with the Unicode format string format, you should enclose literal text in the format string inside single quotes ('
).
If you use a format string with a “%” character to format percentages, the results may be confusing. Consider the following example:
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; |
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; |
[numberFormatter setFormat:@"0.00%;0.00%;-0.00%"]; |
NSNumber *four = [NSNumber numberWithFloat:4.0]; |
NSLog(@"%@", [numberFormatter stringFromNumber:four]); |
// output: "400.00%" |
Because the format string is specified to use percentages, NSNumberFormatter
interprets the number four as a fraction (where 1 is 100%) and renders it as such (4 = 4/1 = 400%).
If you want to represent a number as a percentage, however, you should use the NSNumberFormatterPercentStyle
style—this also ensures that percentages are formatted appropriately for the locale:
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; |
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; |
[numberFormatter setNumberStyle:NSNumberFormatterPercentStyle]; |
NSNumber *four = [NSNumber numberWithFloat:4.0]; |
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; |
[numberFormatter setLocale:usLocale]; |
NSLog(@"en_US: %@", [numberFormatter stringFromNumber:four]); |
// output: "en_US: 400%" |
NSLocale *faLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"fa_IR"]; |
[numberFormatter setLocale:faLocale]; |
NSLog(@"fa_IR: %@", [numberFormatter stringFromNumber:four]); |
// output: "fa_IR: ٪۴۰۰" |
NSNumberFormatter
provides several methods (such as setMaximumFractionDigits:
) that allow you to manage the number of fraction digits allowed as input by an instance. “Fraction digits” are the numbers after the decimal separator (in English locales, the decimal separator is typically referred to as the “decimal point”).
© 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-10-15)