Форматирование валюты Java: принудительно форматировать с использованием символа валюты - PullRequest
3 голосов
/ 29 марта 2011

Я использую средство форматирования валюты весны для форматирования значения на основе кода валюты

public String format(Number number, String currencyCode)
{
    CurrencyFormatter formatter = new CurrencyFormatter();
    formatter.setCurrency(Currency.getInstance(currencyCode));
    return formatter.print(number, Locale.getDefault());        
}

Так что, если я назову его форматом (10, «GBP»), тогда я хочу вернуть значение как £ 10,00,независимо от того, что локаль.

Возможно ли это?

Ответы [ 2 ]

5 голосов
/ 31 июля 2013

Всякий раз, когда вы отображаете валюту, вам нужны две части информации: код валюты и локаль, для которой вы отображаете результат. Например, когда вы отображаете USD в локали en_US, вы хотите, чтобы он показывал $, а в локали en_AU вы хотите, чтобы она отображалась в долларах США (потому что валюта Австралии также называется «долларами», и они используют символ $ для AUD).

Проблема, с которой вы столкнулись, заключается в том, что стандартные средства форматирования валюты Java воняют, когда вы отображаете валюту в «неосновной» локали. То есть почти все в США предпочли бы видеть £ и € при отображении фунтов и евро, но стандартные библиотеки Java показывают «GBP» и «EUR» при отображении этих валют в локали en_US.

Я справился со следующим фрагментом кода. По сути, я указываю свои собственные символы для использования при отображении международных валют:

public static NumberFormat newCurrencyFormat(Currency currency, Locale displayLocale) {
    NumberFormat retVal = NumberFormat.getCurrencyInstance(displayLocale);
    retVal.setCurrency(currency);

    //The default JDK handles situations well when the currency is the default currency for the locale
    if (currency.equals(Currency.getInstance(displayLocale))) {
        return retVal;
    }

    //otherwise we need to "fix things up" when displaying a non-native currency
    if (retVal instanceof DecimalFormat) {
        DecimalFormat decimalFormat = (DecimalFormat) retVal;
        String correctedI18NSymbol = getCorrectedInternationalCurrencySymbol(currency, displayLocale);
        if (correctedI18NSymbol != null) {
            DecimalFormatSymbols dfs = decimalFormat.getDecimalFormatSymbols(); //this returns a clone of DFS
            dfs.setInternationalCurrencySymbol(correctedI18NSymbol);
            dfs.setCurrencySymbol(correctedI18NSymbol);
            decimalFormat.setDecimalFormatSymbols(dfs);
        }
    }

    return retVal;
}

private static String getCorrectedInternationalCurrencySymbol(Currency currency, Locale displayLocale) {
    ResourceBundle i18nSymbolsResourceBundle =
            ResourceBundle.getBundle("correctedI18nCurrencySymbols", displayLocale);
    if (i18nSymbolsResourceBundle.containsKey(currency.getCurrencyCode())) {
        return i18nSymbolsResourceBundle.getString(currency.getCurrencyCode());
    } else {
        return currency.getCurrencyCode();
    }
}

Тогда у меня есть файл свойств (correctedI18nCurrencySymbols.properties), где я указываю символы валюты для использования:

# Note that these are the currency symbols to use for the specified code when displaying in a DIFFERENT locale than
# the home locale of the currency. This file can be edited as needed. In addition, if in some case one specific locale
# would use a symbol DIFFERENT than the standard international one listed here, then an additional properties file
# can be added making use of the standard ResourceBundle loading algorithm. For example, if we decided we wanted to
# show US dollars as just $ instead of US$ when in the UK, we could create a file i18nCurrencySymbols_en_GB.properties
# with the entry USD=$
ARS=$AR
AUD=AU$
BOB=$b
BRL=R$
CAD=CAN$
CLP=Ch$
COP=COL$
CRC=\u20A1
HRK=kn
CZK=K\u010D
DOP=RD$
XCD=EC$
EUR=\u20AC
GTQ=Q
GYD=G$
HNL=L
HKD=HK$
HUF=Ft
INR=\u20B9
IDR=Rp
ILS=\u20AA
JMD=J$
JPY=JP\u00A5
KRW=\u20A9
NZD=NZ$
NIO=C$
PAB=B/.
PYG=Gs
PEN=S/.
PHP=\u20B1
PLN=\u007A\u0142
RON=lei
SGD=S$
ZAR=R
TWD=NT$
THB=\u0E3F
TTD=TT$
GBP=\u00A3
USD=US$
UYU=$U
VEF=Bs
VND=\u20AB
0 голосов
/ 29 марта 2011

Я не знаком с Spring, но проблема заключается в следующем: Locale.getDefault().Вместо этого попробуйте использовать один из статических экземпляров, определенных в классе Locale.

...