Is there a DecimalFormat or NumberFormat equivalen...
# multiplatform
s
Is there a DecimalFormat or NumberFormat equivalent library in KMP which can used to convert a Locale formatted number string with commas and dots to BigDecimal? I basically want to use visualtransformation to convert the numbers entered in a text field to display them in Locale currency and extract the number as BigDecimal from the formatted text. I have an existing implementation in android which I want to port in KMP and make it work in ios. But I could not find a multiplatform library that can achieve this.
👀 1
I could successfully do it with the
expect/actual
route.
Copy code
iosMain

import platform.Foundation.NSLocale
import platform.Foundation.NSNumber
import platform.Foundation.NSNumberFormatter
import platform.Foundation.NSNumberFormatterCurrencyStyle

private val formatter = NSNumberFormatter().apply {
    locale = NSLocale(localeIdentifier = "DE")
    currencyCode = "eur"
    numberStyle = NSNumberFormatterCurrencyStyle
}
actual fun parseFormattedStringToCents(formattedAmount: String): BigInteger {
    return BigInteger(formatter.numberFromString(formattedAmount)?.longValue ?: 0L)
}

actual fun formatMoney(amount: Double): String {
    val number = NSNumber(amount)
    return formatter.stringFromNumber(number) ?: ""
}

-----------------------------------------------------------
commonMain


import com.ionspin.kotlin.bignum.integer.BigInteger

const val defaultFractionDigits = 2

object MoneyFormatter {

    private fun format(value: Double?, forceSign: Boolean = false, forceNegativeSignForZero: Boolean = false): String {
        if (value == null) {
            return ""
        }
        val valueAsString = formatMoney(value)

        return if (value > 0 && forceSign) {
            "+$valueAsString"
        } else if (forceNegativeSignForZero && value.let { it == 0.0}) {
            "-$valueAsString"
        } else {
            valueAsString
        }
    }
    
    fun formatCents(valueInCents: BigInteger) = format(valueInCents.doubleValue() / getFractionDivider().intValue())

    fun parseToCents(formattedMoneyString: String): BigInteger = parseFormattedStringToCents(formattedMoneyString)

    private fun getFractionDivider(): BigInteger {
        var fractionDigits = defaultFractionDigits
        if (fractionDigits < 1) fractionDigits = 0
        return BigInteger.TEN.pow(fractionDigits)
    }
}

expect fun parseFormattedStringToCents(formattedAmount: String): BigInteger
expect fun formatMoney(amount: Double): String

-----------------------------------------------------------------------------------------------
androidMain

import java.text.DecimalFormat
import java.text.NumberFormat
import java.util.Locale

private val decimalFormat: DecimalFormat = NumberFormat.getCurrencyInstance(Locale.GERMANY) as DecimalFormat
actual fun parseFormattedStringToCents(formattedAmount: String): BigInteger =
    BigInteger(decimalFormat.parse(formattedAmount)?.toLong() ?: 0L)

actual fun formatMoney(amount: Double): String =
    decimalFormat.format(amount)