NumberFormatter unable to parse string output that it created

I'm currently adding support for different locales in my app, and one of the things I need to do is let folks input a valid decimal number.

In order to do this I'm using a NumberFormatter with some specific settings:

numberFormatter.locale = .current
numberFormatter.maximumFractionDigits = 2
numberFormatter.minimumFractionDigits = 2
numberFormatter.numberStyle = .decimal
numberFormatter.roundingMode = .halfEven
numberFormatter.usesGroupingSeparator = true

When the locale is set to en-GB or en-US, everything works fine. I'm successfully able to output values as strings, and then use the same number formatter to parse the string back into an NSNumber.

However, if the locale is for a region where spaces are used as a grouping separator, everything breaks.

The number formatter will happily output a value like 1 234.56 via string(from:), but it will fail to parse that exact string as a number using number(from:).

After digging a bit deeper I discovered that, if I create a locale that uses spaces as the grouping separator and check:

numberFormatter.groupingSeparator

The output will be a 0x202f character (NARROW NO-BREAK SPACE).

If I use that same number formatter to output a string value, the space it inserts in 1 000,00 is actually 0xa0.

I think this is why the number formatter's output can't be parsed as valid input, but I'm not sure how to work around this situation.

I ideally need to be able to parse "prettified" values that users have entered in their own locale, so I can't just set the number formatter to always use , as the grouping separator for example.

Any advice would be much appreciated!

Accepted Reply

After more investigation I discovered the root cause here, and it was due to my own misunderstanding.

One of the number formatters had numberStyle set to decimal and another was set to currency. I didn't realise that a different grouping separator was used for currency (currencyGroupingSeparator) vs. other number styles (groupingSeparator), so that's on me for not comprehensively reading the docs!

By ensuring the same grouping separator was applied consistently, this problem went away.

Posting this reply in case anyone else encounters a similar situation and is confused!

  • Thanks for closing the loop here.

Add a Comment

Replies

After more investigation I discovered the root cause here, and it was due to my own misunderstanding.

One of the number formatters had numberStyle set to decimal and another was set to currency. I didn't realise that a different grouping separator was used for currency (currencyGroupingSeparator) vs. other number styles (groupingSeparator), so that's on me for not comprehensively reading the docs!

By ensuring the same grouping separator was applied consistently, this problem went away.

Posting this reply in case anyone else encounters a similar situation and is confused!

  • Thanks for closing the loop here.

Add a Comment