Skip to content

Commit dd172c2

Browse files
committed
SR-7481: NumberFormatter inconsistency on Linux
- 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. (cherry picked from commit c8c16eb)
1 parent 684bb66 commit dd172c2

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

Foundation/NumberFormatter.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ open class NumberFormatter : Formatter {
140140
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterPlusSign, value: _plusSign?._cfObject)
141141
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterCurrencySymbol, value: _currencySymbol?._cfObject)
142142
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterExponentSymbol, value: _exponentSymbol?._cfObject)
143-
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinIntegerDigits, value: _minimumIntegerDigits._bridgeToObjectiveC()._cfObject)
143+
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinIntegerDigits, value: minimumIntegerDigits._bridgeToObjectiveC()._cfObject)
144144
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMaxIntegerDigits, value: _maximumIntegerDigits._bridgeToObjectiveC()._cfObject)
145145
_setFormatterAttribute(formatter, attributeName: kCFNumberFormatterMinFractionDigits, value: _minimumFractionDigits._bridgeToObjectiveC()._cfObject)
146146
if _minimumFractionDigits <= 0 {
@@ -190,12 +190,15 @@ open class NumberFormatter : Formatter {
190190
case .currency, .currencyPlural, .currencyISOCode, .currencyAccounting:
191191
_usesSignificantDigits = false
192192
_usesGroupingSeparator = true
193+
if _minimumIntegerDigits == nil {
194+
_minimumIntegerDigits = 1
195+
}
193196
_minimumFractionDigits = 2
194197

195198
case .decimal:
196199
_usesGroupingSeparator = true
197200
_maximumFractionDigits = 3
198-
if _minimumIntegerDigits == 0 {
201+
if _minimumIntegerDigits == nil {
199202
_minimumIntegerDigits = 1
200203
}
201204
if _groupingSize == 0 {
@@ -680,11 +683,14 @@ open class NumberFormatter : Formatter {
680683
_roundingIncrement = newValue
681684
}
682685
}
683-
684-
internal var _minimumIntegerDigits: Int = 0
686+
687+
// Use an optional for _minimumIntegerDigits to track if the value is
688+
// set BEFORE the .numberStyle is changed. This allows preserving a setting
689+
// of 0.
690+
internal var _minimumIntegerDigits: Int?
685691
open var minimumIntegerDigits: Int {
686692
get {
687-
return _minimumIntegerDigits
693+
return _minimumIntegerDigits ?? 0
688694
}
689695
set {
690696
_reset()

TestFoundation/TestNumberFormatter.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,28 @@ class TestNumberFormatter: XCTestCase {
221221
XCTAssertEqual(numberFormatter.minimumIntegerDigits, 3)
222222
formattedString = numberFormatter.string(from: 0.1)
223223
XCTAssertEqual(formattedString, "000.1")
224+
225+
numberFormatter.numberStyle = .currency
226+
XCTAssertEqual(numberFormatter.minimumIntegerDigits, 3)
227+
228+
// If .minimumIntegerDigits is set to 0 before .numberStyle change, preserve the value
229+
let currencyFormatter = NumberFormatter()
230+
XCTAssertEqual(currencyFormatter.minimumIntegerDigits, 0)
231+
currencyFormatter.minimumIntegerDigits = 0
232+
currencyFormatter.numberStyle = .currency
233+
XCTAssertEqual(currencyFormatter.minimumIntegerDigits, 0)
234+
currencyFormatter.locale = Locale(identifier: "en_US")
235+
formattedString = currencyFormatter.string(from: NSNumber(value: 0))
236+
XCTAssertEqual(formattedString, "$.00")
237+
238+
// If .minimumIntegerDigits is not set before .numberStyle change, update the value
239+
let currencyFormatter2 = NumberFormatter()
240+
XCTAssertEqual(currencyFormatter2.minimumIntegerDigits, 0)
241+
currencyFormatter2.numberStyle = .currency
242+
XCTAssertEqual(currencyFormatter2.minimumIntegerDigits, 1)
243+
currencyFormatter2.locale = Locale(identifier: "en_US")
244+
formattedString = currencyFormatter2.string(from: NSNumber(value: 0))
245+
XCTAssertEqual(formattedString, "$0.00")
224246
}
225247

226248
func test_maximumIntegerDigits() {

0 commit comments

Comments
 (0)