-3

I have my app in Android that has a yearly subscription. I would like to display to the user the price also in months (so it looks more attractive). For example, let's say the yerly subscription is $12, I want to display someting like this:

Get this subscription for only $1/month (billed as yearly payments of $12)

I looks as simple as dividing the price of the subscription by 12 moths, but I am stragling with the currency symbol. Some locales will display de symbol in the left, others in the right. For example in Spanish it will be "12€".

Is there a way to detect that?

I am having toying with

float fYearPerice = mySkuDetails.getPriceAmountMicros() / 1000000.0f; float fMonthPrice = oSubscripcion.fPrecio/12; String sCurrencyCode = oSkuDetails.getPriceCurrencyCode();

I can do something as simple as this:

String s = "Get this subscription for only " + sCurrencyCode  + fMonthPrice  + "/month (billed as yearly payments of " + mySkuDetails.getPrice();

But the currency will not be in the right position for every locale. Is there a way to approach this elegantly?

Ton
  • 9,235
  • 15
  • 59
  • 103
  • Seems to be a duplicate of https://stackoverflow.com/questions/43752248/how-to-determine-where-to-place-the-currency-symbol-when-formatting-a-number. Also note that using floating point types for currency is going to cause representation errors at some point. You should be using BigDecimal for currency operations. – aled Aug 01 '23 at 11:25
  • Seems possible to use Locale strings.xml and using format arguments to replace actual values: this [answer](https://stackoverflow.com/questions/3656371/is-it-possible-to-have-placeholders-in-strings-xml-for-runtime-values) touches on it. You can therefore customize each "subscription" message per supported locale. [Resources.getString](https://developer.android.com/reference/android/content/res/Resources#getString(int,%20java.lang.Object[])) is the useful method. – Computable Aug 01 '23 at 11:39

1 Answers1

0

Updated as per request to make it more generic:

import java.text.NumberFormat;
import java.util.Locale;

public class CurrencyFormatter {

    public enum LanguageCode {
        EN, ES, FR // Add more language codes as needed
    }

    public enum CountryCode {
        US, ES, FR, GB // Add more country codes as needed
    }

    public static void main(String[] args) {
        String stringSpain = getFormattedCurrencyString(LanguageCode.ES, CountryCode.ES, 1f, 12f);
        System.out.println(stringSpain);

        String stringFrance = getFormattedCurrencyString(LanguageCode.FR, CountryCode.FR, 1f, 12f);
        System.out.println(stringFrance);

        String stringUK = getFormattedCurrencyString(LanguageCode.EN, CountryCode.GB, 1f, 12f);
        System.out.println(stringUK);

        String stringUS = getFormattedCurrencyString(LanguageCode.EN, CountryCode.US, 1f, 12f);
        System.out.println(stringUS);
    }

    public static String getFormattedCurrencyString(LanguageCode languageCode, CountryCode countryCode, float monthlyPrice, float yearlyPrice) {
        Locale locale = Locale.forLanguageTag(languageCode.name() + "-" + countryCode.name());
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(locale);
        String formattedMonthlyPrice = currencyFormat.format(monthlyPrice);
        String formattedYearlyPrice = currencyFormat.format(yearlyPrice);
        return "Get this subscription for only " + formattedMonthlyPrice + "/month (billed as yearly payments of " + formattedYearlyPrice + ")";
    }
}

This should work fine:

Locale countryLocaleSpain = Locale.of("es", "ES");
NumberFormat currencyFormatSpain = NumberFormat.getCurrencyInstance(countryLocaleSpain);
String stringSpain = "Get this subscription for only " + currencyFormatSpain.format(1f)  + "/month (billed as yearly payments of " + currencyFormatSpain.format(12f);
System.out.println(stringSpain);

Locale countryLocaleFrance = Locale.FRANCE;
NumberFormat currencyFormatFrance = NumberFormat.getCurrencyInstance(countryLocaleFrance);
String stringFrance = "Get this subscription for only " + currencyFormatFrance.format(1f)  + "/month (billed as yearly payments of " + currencyFormatFrance.format(12f);
System.out.println(stringFrance);

Locale countryLocaleUK = Locale.UK;
NumberFormat currencyFormatUK = NumberFormat.getCurrencyInstance(countryLocaleUK);
String stringUK = "Get this subscription for only " + currencyFormatUK.format(1f)  + "/month (billed as yearly payments of " + currencyFormatUK.format(12f);
System.out.println(stringUK);

Locale countryLocaleUS = Locale.US;
NumberFormat currencyFormatUS = NumberFormat.getCurrencyInstance(countryLocaleUS);
String stringUS = "Get this subscription for only " + currencyFormatUS.format(1f)  + "/month (billed as yearly payments of " + currencyFormatUS.format(12f);
System.out.println(stringUS);

Output:

Get this subscription for only 1,00 €/month (billed as yearly payments of 12,00 €
Get this subscription for only 1,00 €/month (billed as yearly payments of 12,00 €
Get this subscription for only £1.00/month (billed as yearly payments of £12.00
Get this subscription for only $1.00/month (billed as yearly payments of $12.00
BernardV
  • 640
  • 10
  • 28