Search code examples
iosswiftnumber-formattingnsnumberformatter

Is there any format description compatible with Java and Swift?


In Java there is DecimalFormat which supports

  • ###.## -> 3.14
  • 0 -> 3
  • 00.000 -> 03.142
  • #.##% -> 314.16%
  • pie is ###.## -> pie is 3.14

but I cannot find an equivalent function in Swift for iOS.

There is NumberFormatter, but that does not support pie is ###.##, and setting all properties in code is inconvenient:

formatter.maximumFractionDigits = 2
formatter.numberStyle = .currencyAccounting

I am curious about if there is a format both supported by Java & Swift, that will be very useful in React Native (define the format in js)


Solution

  • (NS)NumberFormatter has positiveFormat and negativeFormat properties, which are format patterns according to the Unicode Technical Standard #35. These seem to be compatible with the Java DecimalFormat.

    Examples:

    let posNumber = NSNumber(value: Double.pi)
    let negNumber = NSNumber(value: -Double.pi)
    
    let f1 = NumberFormatter()
    f1.positiveFormat = "00.000"
    print(f1.string(from: posNumber)!) // 03.142
    print(f1.string(from: negNumber)!) // -03.142
    
    let f2 = NumberFormatter()
    f2.positiveFormat = "pie is ###.## "
    print(f2.string(from: posNumber)!) // pie is 3.14
    

    The numbers are formatted according to the current locale (so the output can be 3,14 as well). If that is not intended, add

    f2.locale = Locale(identifier: "en_US_POSIX")
    

    If you don't set negativeFormat then the positive format with a prepended minus sign will be used for negative numbers. That works well in the first example, but not with custom text:

    print(f2.string(from: negNumber)!) // -pie is 3.14
    

    This is solved by setting both the positive and negative format:

    let f3 = NumberFormatter()
    f3.positiveFormat = "Result is 00.000"
    f3.negativeFormat = "Result is -00.000"
    print(f3.string(from: posNumber)!) // Result is 03.142
    print(f3.string(from: negNumber)!) // Result is -03.142
    

    On macOS, the format property can be used instead, positive and (optional) negative format are separated by a semicolon. In the above examples that would be:

    f2.format = "pie is ###.##"
    
    f3.format = "Result is 00.000;Result is -00.000"