这是我在Moneta 1.1 版中使用的示例代码:
Locale LANG = Locale.CHINA; // also tried new Locale("pl", "PL");
final MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(
AmountFormatQueryBuilder.of(LANG)
.set(CurrencyStyle.SYMBOL)
.set("pattern", "#,##0.00### ¤")
.build()
);
final String formatted = format.format(Money.of(new BigDecimal("1234.56"), Monetary.getCurrency(LANG)));
System.out.println(formatted);
System.out.println(format.parse(formatted).getNumber());
这应该可以工作,因为我正在来回转换同一个对象。除非我做错了什么,并且转换器不是美元、欧元或英镑以外的其他货币的双向转换器。
最后一行崩溃:
Exception in thread "main" java.lang.IllegalArgumentException: Invalid error index > input.length
at javax.money.format.MonetaryParseException.<init>(MonetaryParseException.java:56)
at org.javamoney.moneta.internal.format.AmountNumberToken.parse(AmountNumberToken.java:140)
at org.javamoney.moneta.internal.format.DefaultMonetaryAmountFormat.parse(DefaultMonetaryAmountFormat.java:190)
at test.main(test.java:27)
如果提供的语言环境不与 $、€ 或 £ 之一相关联,则会发生这种情况。例如,此代码适用于Locale.US
,但会崩溃Locale.CHINA
以及 with new Locale("pl", "PL")
。因此,这不仅是自定义定义Locale
的问题,也是静态预定义的问题。
我挖了一点内部包,发现org.javamoney.moneta.internal.format.CurrencyToken.parse(CurrencyToken.java:196)
它看起来像:
case SYMBOL:
if (token.startsWith("$")) {
cur = Monetary.getCurrency("USD");
context.consume("$");
} else if (token.startsWith("€")) {
cur = Monetary.getCurrency("EUR");
context.consume("€");
} else if (token.startsWith("£")) {
cur = Monetary.getCurrency("GBP");
context.consume("£");
} else {
cur = Monetary.getCurrency(token);
context.consume(token);
}
context.setParsedCurrency(cur);
break;
有什么方法可以使我的上述代码适用于美元、欧元或英镑以外的货币?
我尝试了更多的东西,例如提供 Locale.CANADA 他们也有 $ 作为货币符号,所以它执行没有失败但返回错误的数据
Locale LANG = Locale.CANADA;
final MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(
AmountFormatQueryBuilder.of(LANG)
.set(CurrencyStyle.SYMBOL)
.set("pattern", "#,##0.00### ¤")
.build()
);
final String formatted = format.format(Money.of(new BigDecimal("1234.56"), Monetary.getCurrency(LANG)));
System.out.println(formatted);
System.out.println(format.parse(formatted).getCurrency().getCurrencyCode());
最后一行返回USD
而不是CAD
if-else 对 $ 所做的。我认为它也错误地假设符号 - 货币是一对一的映射。