Java 货币格式化程序:强制使用货币符号进行格式化

发布于 2024-10-27 09:25:41 字数 392 浏览 0 评论 0原文

我使用 spring 货币格式化程序根据货币代码格式化一个值,

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

因此,如果我将其称为 format(10, "GBP"),那么我希望该值返回为 £10.00,无论区域设置是什么。

这可能吗?

I use the spring currency formatter to format a value based on currency code

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

So if I call it as format(10, "GBP") then I want the value back as £10.00, no matter what the locale is.

Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

两仪 2024-11-03 09:25:41

每当显示货币时,您都需要两条信息:货币代码和显示结果的区域设置。例如,当您在 en_US 语言环境中显示 USD 时,您希望它显示 $,但在 en_AU 语言环境中,您希望它显示为 US$(因为澳大利亚的货币也称为“美元”,他们使用 $ 符号表示澳元)。

您遇到的问题是,当您在“非主要”区域设置中显示货币时,常用的 Java 货币格式化程序会很糟糕。也就是说,几乎每个美国人在显示英镑和欧元时都更愿意看到英镑和欧元,但在 en_US 语言环境中显示这些货币时,库存 Java 库会显示“GBP”和“EUR”。

我用下面的代码解决了这个问题。我基本上指定了在显示国际货币时要使用的自己的符号:

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

Whenever you display a currency, you need two pieces of info: the currency code, and the locale for which you are displaying a result. For example, when you display USD in the en_US locale, you want it to show $, but in the en_AU locale, you want it to show as US$ (because Australia's currency is also called "dollars" and they use the $ symbol for AUD).

The issue you've hit is that the stock Java currency formatters stink when you are displaying a currency in its "non-primary" locale. That is, pretty much everyone in the US would rather see £ and € when showing pounds and euros, but the stock Java libraries show "GBP" and "EUR" when showing those currencies in the en_US locale.

I got around this with the following piece of code. I essentially specify my own symbols to use when displaying international currencies:

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();
    }
}

Then I have my properties file (correctedI18nCurrencySymbols.properties) where I specify currency symbols to use:

# 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
江南烟雨〆相思醉 2024-11-03 09:25:41

我不熟悉 Spring,但以下似乎是问题所在:Locale.getDefault()。相反,请尝试使用 Locale 类中定义的静态实例之一。

I am not familiar with Spring, but the following appears to be the issue: Locale.getDefault(). Instead, try using one of the static instances defined on the Locale class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文