Search code examples
androidkotlincurrency-formatting

How to generate a price string with a currency symbol (e.g. $) instead of currency code (USD, EUR)?


This is my current code:

fun getMonthlyPriceString(yearlyPriceMicros: Long, currencyCode: String): String  {
    val format: NumberFormat = NumberFormat.getCurrencyInstance()
    format.maximumFractionDigits = 2
    format.currency = Currency.getInstance(currencyCode)

    return format.format(yearlyPriceMicros.toFloat() / 1_000_000f / 12)
}

This produces: "SGD 5.00". However I want a price string like "$5.00" (with the symbol) instead.

The currencyCode argument is retrieved from an external API (RevenueCat) and is in the form "EUR", "USD", "SGD", etc.

I have tried replacing the code on line 4 with

format.currency = Currency.getInstance(Locale.getDefault())

But this produces: "£5.00" which is the wrong symbol (pounds) because I am based in Singapore and thus it should be "$5.00" (singapore dollars)


Solution

  • Firstly, I realised my language was set to "English (United Kingdom)" which was why the price was being displayed in pounds when using format.currency = Currency.getInstance(Locale.getDefault()). So changing my language to English (Singapore) fixed the issue.

    However, I still wanted to display the currency based on the given currencyCode parameter in the function despite the default locale.

    Thus, I managed to use the newer NumberFormatter api to achieve this:

    fun getMonthlyPriceString(yearlyPriceMicros: Long, currencyCode: String): String {
        val monthlyPrice = yearlyPriceMicros.toFloat() / 1_000_000f / 12
    
        return NumberFormatter.with()
                .unit(Currency.getInstance(currencyCode)) // <-- Can pass the currency code from the function parameter here
                .precision(Precision.currency(Currency.CurrencyUsage.STANDARD)) // <-- This handles the decimal places for you
                .locale(Locale.getDefault()) // <-- Will still show the correct currency but in the user's locale
                .format(monthlyPrice)
                .toString()
    }
    

    Note that NumberFormatter is only available from SDK Level 30 (Android 11) and above.