问题描述
以下是我与 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());
这应该可行,因为我正在来回转换相同的对象.除非我弄错了,并且换算为美元,欧元或英镑以外的其他货币,汇率不是双向的.
This should work since I'm converting same object back and forth. Unless I got something wrong and converter is not two-way for other currencies than $, € or £.
最后一行崩溃:
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
和new Locale("pl", "PL")
崩溃.因此,这不仅是自定义定义的Locale
的问题,还是静态定义的问题.
This happens if provided locale is not associated with one of $, € or £. For instance this code will work for Locale.US
, but will crash for Locale.CHINA
as well as with new Locale("pl", "PL")
. So this is not only problem with custom defined Locale
but those statically predefined as well.
我在内部包装中挖了一点,发现了org.javamoney.moneta.internal.format.CurrencyToken.parse(CurrencyToken.java:196)
,它看起来像:
I have dug a little into the internal package and found org.javamoney.moneta.internal.format.CurrencyToken.parse(CurrencyToken.java:196)
, which looks like:
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;
有什么方法可以使我的代码适用于美元,欧元或英镑以外的货币?
Is there any way to make my code above work for currencies other than $, € or £?
例如,我尝试了一些其他的事情,例如Locale.CANADA,它们也有$作为货币符号,因此它可以执行而不会失败,但是返回错误的数据
I have try few more things for instance provided Locale.CANADA they also have $ as currency symbol so it execute without failure but returns wrong data
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为$执行的操作.我认为它也错误地假设符号-货币是一对一的映射.
last line return USD
instead of CAD
which is what this if-else does for $. I think it also wrongly assumes that symbol - currency is one to one mapping.
推荐答案
我们正在研究解决方案,出现了问题 https://github.com/JavaMoney/jsr354-ri/issues/149 .
We're working on a solution, issues raised https://github.com/JavaMoney/jsr354-ri/issues/149.
期待Moneta修补程序很快解决此问题和其他问题.
Expect Moneta patches for this and other issues soon.
维尔纳
这篇关于JSR-354 MonetaryAmountFormat对于除$,€或£以外的其他货币符号不起作用的两种方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!