OpenJDK 11下NumberFormat输出货币符号而非货币代码的问题求助
问题根因
默认NumberFormat.getCurrencyInstance()创建的货币格式化器,会读取对应地区的默认格式配置,优先展示当地通用的货币符号(比如印度卢比的₹、美元的$),而非ISO 4217标准的三位货币代码。
另外你的现有代码存在一处逻辑错误:locale.toString()返回的是「语言代码_国家代码」格式的拼接字符串(比如印度英语对应en_IN),但Locale构造函数第一个入参要求传入纯语言代码(比如en),传入拼接后的字符串会生成无效Locale,进一步加剧格式不符合预期的问题。
修复方案
方案1:最小改动适配原有逻辑,保留地区数字格式规则
只需要在创建格式化器之后,强制替换货币符号为ISO货币代码即可,代码修改如下:
public static void main(String[] args) { Currency currency = getCurrency(356); String currencyCode = currency.getCurrencyCode(); Locale locale = getLocalFromISO(currencyCode); // 直接用查询到的合法Locale创建格式化器,无需重复构造 NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(locale); // 强制设置货币符号为ISO三位代码 if (currencyFormatter instanceof DecimalFormat) { DecimalFormat decimalFormat = (DecimalFormat) currencyFormatter; DecimalFormatSymbols symbols = decimalFormat.getDecimalFormatSymbols(); symbols.setCurrencySymbol(currencyCode); decimalFormat.setDecimalFormatSymbols(symbols); } // 不需要小数位可添加下面这行配置 // currencyFormatter.setMaximumFractionDigits(0); System.out.println("Formated Amount---->" + currencyFormatter.format(100000000)); } // 工具方法补充异常兼容逻辑,避免部分无货币配置的区域报错 public static Currency getCurrency(int numericCurrencyCode) { Currency currencyOutput = null; for (Currency currency : Currency.getAvailableCurrencies()) { if (currency.getNumericCode() == numericCurrencyCode) { currencyOutput = currency; break; } } return currencyOutput; } public static Locale getLocalFromISO(String iso4217code){ Locale locl = null; for (Locale locale : NumberFormat.getAvailableLocales()) { try{ String code = NumberFormat.getCurrencyInstance(locale).getCurrency().getCurrencyCode(); if (iso4217code.equals(code)) { locl = locale; break; } }catch (Exception e){ // 跳过不支持货币格式化的区域即可 } } return locl; }
调整后1000的输出结果即为INR 1,000,完全符合预期。
方案2:自定义固定格式,不依赖地区规则
如果不需要适配不同地区的数字分隔、小数位规则,可以直接自定义模式串实现:
public static String formatCurrencyWithCode(double amount, String currencyCode) { DecimalFormat df = new DecimalFormat(currencyCode + " #,###"); return df.format(amount); } // 调用测试 System.out.println(formatCurrencyWithCode(1000, "INR")); // 输出INR 1,000
内容的提问来源于stack exchange,提问作者Vadiraj Hebbar
相关产品推荐
相关产品推荐

