Skip to content

Commit c8c16eb

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.
1 parent 6c54c84 commit c8c16eb

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
@@ -229,6 +229,28 @@ class TestNumberFormatter: XCTestCase {
229229
XCTAssertEqual(numberFormatter.minimumIntegerDigits, 3)
230230
formattedString = numberFormatter.string(from: 0.1)
231231
XCTAssertEqual(formattedString, "000.1")
232+
233+
numberFormatter.numberStyle = .currency
234+
XCTAssertEqual(numberFormatter.minimumIntegerDigits, 3)
235+
236+
// If .minimumIntegerDigits is set to 0 before .numberStyle change, preserve the value
237+
let currencyFormatter = NumberFormatter()
238+
XCTAssertEqual(currencyFormatter.minimumIntegerDigits, 0)
239+
currencyFormatter.minimumIntegerDigits = 0
240+
currencyFormatter.numberStyle = .currency
241+
XCTAssertEqual(currencyFormatter.minimumIntegerDigits, 0)
242+
currencyFormatter.locale = Locale(identifier: "en_US")
243+
formattedString = currencyFormatter.string(from: NSNumber(value: 0))
244+
XCTAssertEqual(formattedString, "$.00")
245+
246+
// If .minimumIntegerDigits is not set before .numberStyle change, update the value
247+
let currencyFormatter2 = NumberFormatter()
248+
XCTAssertEqual(currencyFormatter2.minimumIntegerDigits, 0)
249+
currencyFormatter2.numberStyle = .currency
250+
XCTAssertEqual(currencyFormatter2.minimumIntegerDigits, 1)
251+
currencyFormatter2.locale = Locale(identifier: "en_US")
252+
formattedString = currencyFormatter2.string(from: NSNumber(value: 0))
253+
XCTAssertEqual(formattedString, "$0.00")
232254
}
233255

234256
func test_maximumIntegerDigits() {

0 commit comments

Comments
 (0)