Skip to content

Commit

Permalink
SR-7481: NumberFormatter inconsistency on Linux
Browse files Browse the repository at this point in the history
- For the numberStyle .currency, use a minimumIntegerDigits of 1.

- If minimumIntegerDigits is set to any value (including 0) before
  the numberStyle is set, preserve the original value.
  • Loading branch information
spevans committed Apr 21, 2018
1 parent 6c54c84 commit c8c16eb
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
16 changes: 11 additions & 5 deletions Foundation/NumberFormatter.swift
Expand Up @@ -140,7 +140,7 @@ open class NumberFormatter : Formatter {
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterPlusSign, value: _plusSign?._cfObject)
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterCurrencySymbol, value: _currencySymbol?._cfObject)
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterExponentSymbol, value: _exponentSymbol?._cfObject)
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinIntegerDigits, value: _minimumIntegerDigits._bridgeToObjectiveC()._cfObject)
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinIntegerDigits, value: minimumIntegerDigits._bridgeToObjectiveC()._cfObject)
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMaxIntegerDigits, value: _maximumIntegerDigits._bridgeToObjectiveC()._cfObject)
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinFractionDigits, value: _minimumFractionDigits._bridgeToObjectiveC()._cfObject)
if _minimumFractionDigits <= 0 {
Expand Down Expand Up @@ -190,12 +190,15 @@ open class NumberFormatter : Formatter {
case .currency, .currencyPlural, .currencyISOCode, .currencyAccounting:
_usesSignificantDigits = false
_usesGroupingSeparator = true
if _minimumIntegerDigits == nil {
_minimumIntegerDigits = 1
}
_minimumFractionDigits = 2

case .decimal:
_usesGroupingSeparator = true
_maximumFractionDigits = 3
if _minimumIntegerDigits == 0 {
if _minimumIntegerDigits == nil {
_minimumIntegerDigits = 1
}
if _groupingSize == 0 {
Expand Down Expand Up @@ -680,11 +683,14 @@ open class NumberFormatter : Formatter {
_roundingIncrement = newValue
}
}

internal var _minimumIntegerDigits: Int = 0

// Use an optional for _minimumIntegerDigits to track if the value is
// set BEFORE the .numberStyle is changed. This allows preserving a setting
// of 0.
internal var _minimumIntegerDigits: Int?
open var minimumIntegerDigits: Int {
get {
return _minimumIntegerDigits
return _minimumIntegerDigits ?? 0
}
set {
_reset()
Expand Down
22 changes: 22 additions & 0 deletions TestFoundation/TestNumberFormatter.swift
Expand Up @@ -229,6 +229,28 @@ class TestNumberFormatter: XCTestCase {
XCTAssertEqual(numberFormatter.minimumIntegerDigits, 3)
formattedString = numberFormatter.string(from: 0.1)
XCTAssertEqual(formattedString, "000.1")

numberFormatter.numberStyle = .currency
XCTAssertEqual(numberFormatter.minimumIntegerDigits, 3)

// If .minimumIntegerDigits is set to 0 before .numberStyle change, preserve the value
let currencyFormatter = NumberFormatter()
XCTAssertEqual(currencyFormatter.minimumIntegerDigits, 0)
currencyFormatter.minimumIntegerDigits = 0
currencyFormatter.numberStyle = .currency
XCTAssertEqual(currencyFormatter.minimumIntegerDigits, 0)
currencyFormatter.locale = Locale(identifier: "en_US")
formattedString = currencyFormatter.string(from: NSNumber(value: 0))
XCTAssertEqual(formattedString, "$.00")

// If .minimumIntegerDigits is not set before .numberStyle change, update the value
let currencyFormatter2 = NumberFormatter()
XCTAssertEqual(currencyFormatter2.minimumIntegerDigits, 0)
currencyFormatter2.numberStyle = .currency
XCTAssertEqual(currencyFormatter2.minimumIntegerDigits, 1)
currencyFormatter2.locale = Locale(identifier: "en_US")
formattedString = currencyFormatter2.string(from: NSNumber(value: 0))
XCTAssertEqual(formattedString, "$0.00")
}

func test_maximumIntegerDigits() {
Expand Down

0 comments on commit c8c16eb

Please sign in to comment.