【问题标题】:How to get NumberFormat instance from currency code?如何从货币代码中获取 NumberFormat 实例?
【发布时间】:2012-03-19 20:47:08
【问题描述】:

如何获取与 ISO 4217 货币代码(例如“EUR”或“USD”)对应的NumberFormat(或DecimalFormat)实例以便正确格式化价格?

注意 1: 我遇到的问题是 NumberFormat/DecimalFormat 类有一个 getCurrencyInstance(Locale locale) 方法,但我不知道如何 从 ISO 4217 货币代码获取 Locale 对象。

注意 2: 还有一个 java.util.Currency 类,它有一个 getInstance(String currencyCode) 方法(返回 Currency 例如给定的 ISO 4217 货币代码)但我又想不通 了解如何从 Currency 对象到 NumberFormat 实例...

【问题讨论】:

    标签: java


    【解决方案1】:

    我不确定我是否理解正确,但您可以尝试以下方法:

    public class CurrencyTest
    {
        @Test
        public void testGetNumberFormatForCurrencyCode()
        {
            NumberFormat format = NumberFormat.getInstance();
            format.setMaximumFractionDigits(2);
            Currency currency = Currency.getInstance("USD");
            format.setCurrency(currency);
    
            System.out.println(format.format(1234.23434));
        }   
    }
    

    输出:

    1,234.23
    

    请注意,我单独设置了最大小数位数,NumberFormat.setCurrency 不会触及最大小数位数:

    在格式化货币时设置此数字格式使用的货币 价值观。这不会更新分数的最小或最大数量 数字格式使用的数字。

    【讨论】:

    • 这个解决方案并不理想,因为货币有时会以“0.69 加元”的格式显示,而不是 Spencer Kormos 提到的“0.69 美元”,但发现这个解决方案是最简单和最干净的,并且需要继续前进,所以就这样去了。刚刚做了一项更改——我没有拨打format.setMaximumFractionDigits(2);,而是拨打format.setMaximumFractionDigits(currency.getDefaultFractionDigits());
    • 我建议使用NumberFormat.getCurrencyInstance() 而不仅仅是getInstance()
    • 我想这是为import java.text.NumberFormat; 而不是import android.icu.text.NumberFormat;。似乎 android.icu.text.NumberFormat 中 NumberFormat 中的 setMaximumFractionDigits 和 setCurrency 仅适用于最低 API 级别 24。
    • @esaj,当货币格式为“美元”时,需要进行哪些更改才能显示带有输出数字的$? (希望得到像$1,234.23 这样的输出)
    【解决方案2】:

    Locale 既可以用于获取 Locale 的标准货币,也可以在您指定的 locale 中正确打印 any 货币符号。这是两个不同的操作,并不真正相关。

    Java Internationalization tutorial,您首先使用区域设置或 ISO 代码获得货币的实例。然后您可以使用 another 语言环境打印符号。因此,如果您从 en_US 语言环境中获取美国货币,并调用 getSymbol(),它将打印“$”。但是,如果您使用英国语言​​环境调用 getSymbol(Locale),它将打印“USD”。

    因此,如果您不关心当前用户的区域设置,而只关心货币,那么您可以在所有情况下忽略区域设置。

    如果您关心根据当前用户正确表示货币符号,那么您需要获取特定于用户位置的用户语言环境

    【讨论】:

    • 就像 esaj 提到的那样,设置小数位格式的是货币而不是语言环境。 Locale 只是如何显示货币符号和小数点分隔符。
    【解决方案3】:

    映射有时是一对多的……就像许多国家(地区)使用欧元一样……

    只是因为货币代码相同,格式可能会有所不同,如本例所示:

    private static Collection<Locale> getLocalesFromIso4217(String iso4217code) {
        Collection<Locale> returnValue = new LinkedList<Locale>();
        for (Locale locale : NumberFormat.getAvailableLocales()) {
            String code = NumberFormat.getCurrencyInstance(locale).
            getCurrency().getCurrencyCode();
            if (iso4217code.equals(code)) {
                returnValue.add(locale);
            }
        }  
        return returnValue;
    }
    
    public static void main(String[] args) {
        System.out.println(getLocalesFromIso4217("USD"));
        System.out.println(getLocalesFromIso4217("EUR"));
        for (Locale locale : getLocalesFromIso4217("EUR")) {
            System.out.println(locale + "=>" + NumberFormat.getCurrencyInstance(locale).format(1234));
        }
    }
    

    输出

    [en_US, es_US, es_EC, es_PR]
    [pt_PT, el_CY, fi_FI, en_MT, sl_SI, ga_IE, fr_BE, es_ES, de_AT, nl_NL, el_GR, it_IT, en_IE, fr_LU, nl_BE, ca_ES, sr_ME, mt_MT, fr_FR, de_DE, de_LU]
    
    pt_PT=>1.234,00 €
    el_CY=>€1.234,00
    fi_FI=>1 234,00 €
    en_MT=>€1,234.00
    sl_SI=>€ 1.234
    ga_IE=>€1,234.00
    fr_BE=>1.234,00 €
    es_ES=>1.234,00 €
    de_AT=>€ 1.234,00
    nl_NL=>€ 1.234,00
    el_GR=>1.234,00 €
    it_IT=>€ 1.234,00
    en_IE=>€1,234.00
    fr_LU=>1 234,00 €
    nl_BE=>1.234,00 €
    ca_ES=>€ 1.234,00
    sr_ME=>€ 1.234,00
    mt_MT=>€1,234.00
    fr_FR=>1 234,00 €
    de_DE=>1.234,00 €
    de_LU=>1.234,00 €
    

    【讨论】:

      【解决方案4】:

      为了完整起见,虽然我从未使用过它,但您可能想尝试一下Joda Money。如果它和 Joda-Time 一样好,它可能比标准 JDK 的东西更容易、更强大。

      【讨论】:

        【解决方案5】:

        试试下面的方法:

        private static NumberFormat getNumberFormat(String currencyCode)
        {
            Currency currency = Currency.getInstance(currencyCode);
        
            Locale[] locales = NumberFormat.getAvailableLocales();
        
            for (Locale locale : locales)
            {
                NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale);
        
                if (numberFormat.getCurrency() == currency)
                    return numberFormat;
            }
        
            return null;
        }
        

        【讨论】:

        • 感谢伯纳德的回复。不幸的是,正如 Adam 所指出的,存在一个问题,即给定的货币代码可以映射到多个语言环境......
        【解决方案6】:
        public class PriceHelper {
            public static String formatPrice(Context context, String currencyCode, 
                                              double price) {
                if (price == 0) {
                    return context.getString(R.string.free);
                }
                Currency currency = Currency.getInstance(currencyCode);
                NumberFormat format = NumberFormat.getCurrencyInstance();
                format.setCurrency(currency);
                return format.format(price);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2014-12-07
          • 2012-10-22
          • 2012-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多