我真的很困惑如何使用MonetaJSR-354实现定制MonetaryAmountFormat。
我的意图是能够将1.23和$3.45解析为MonetaryAmount。
这是我的单元测试:
@Test
public void testString() {
Bid bid = new Bid("1.23");
assertEquals(1.23, bid.getValue(), 0.0);
System.out.println(bid);
bid = new Bid("$3.45");
assertEquals(3.45, bid.getValue(), 0.0);
System.out.println(bid);
}这是我的班级:
public final class Bid {
private static final CurrencyUnit USD = Monetary.getCurrency("USD");
private MonetaryAmount bid;
/**
* Constructor.
*
* @param bidStr the bid
*/
public Bid(String bidStr) {
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(
AmountFormatQueryBuilder.of(Locale.US)
.set("pattern", "###.##")
.build());
if (StringUtils.isNotBlank(bidStr)) {
bidStr = bidStr.trim();
bidStr = bidStr.startsWith("$") ? bidStr.substring(1) : bidStr;
try {
bid = FastMoney.parse(bidStr, format);
} catch (NumberFormatException e) {
bid = FastMoney.of(0, USD);
}
}
}
/**
* Constructor.
*
* @param bidDouble the bid
*/
public Bid(double bidDouble) {
bid = FastMoney.of(bidDouble, USD);
}
public double getValue() {
return bid.getNumber().doubleValue();
}
}我非常希望能够使用单一的bidStr来解析带有或不使用$的MonetaryAmountFormat,但是在花了大量时间试图找出如何使$成为可选的之后,我放弃了。不幸的是,我甚至不知道如何使1.23被解析为美元。Moneta抛出一个NullPointerException。我应该使用AmountFormatQueryBuilder来设置货币吗?使用AmountFormatQueryBuilder可以设置的所有键是什么?我搜索文档,但找不到任何地方,除了几个普通的密钥,如pattern。
发布于 2016-04-29 22:41:01
当试图解析不合格的数字时,JavaMoney似乎不能很好地工作(如1.23)。
默认情况下,MonetaryAmountFormat希望您提供货币名称(如USD 1.23):
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.US);
MonetaryAmount amount = format.parse("USD 1.23");如果设置了CurrencyStyle.SYMBOL,则可以按货币名称或符号解析(所以,USD 1.23或$3.45):
AmountFormatQuery formatQuery = AmountFormatQueryBuilder.of(Locale.US)
.set(CurrencyStyle.SYMBOL)
.build();
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(formatQuery);
MonetaryAmount amount1 = format.parse("USD 1.23");
MonetaryAmount amount2 = format.parse("$3.45");这可能是你在JavaMoney上最接近的。
如果您知道您只从同一货币获得数字,那么最好在其他地方解析字符串(使用regexs或其他什么的)并转换为一致的输入格式,因为(正如您所发现的),当NullPointerException不高兴时,您很容易得到没有任何解释的JavaMoney。
至于可用的键,您可以查看org.javamoney.moneta.format.AmountFormatParams上的常量:pattern、groupingSizes、groupingSeparators。
在设置格式时,必须注意必须使用通用的货币符号:¤。例如,您可以执行.set("pattern", "¤#,##0.00")。
最后,与其直接使用Moneta中的FastMoney类,不如直接从MonetaryAmountFormat解析
// rather than using Monata directly:
MonetaryAmount amount = FastMoney.parse(bidStr, format);
// use the API:
MonetaryAmount amount = format.parse(bidStr);发布于 2019-02-17 20:15:50
如果您使用的是自定义格式模式,那么您可以解析字符串,它只包含一个没有货币的数字,但是您应该自己指定预期的货币。下面是一个示例:
@Test
public void testParse_pattern_without_currency_sign_but_with_currency_in_context() {
CurrencyUnit usd = Monetary.getCurrency("USD");
AmountFormatContextBuilder builder = AmountFormatContextBuilder.of(US);
builder.set(AmountFormatParams.PATTERN, "0.00"); // the pattern doesn't contains a currency sign ¤
builder.set(CurrencyUnit.class, usd); // set expected currency
AmountFormatContext context = builder.build();
DefaultMonetaryAmountFormat format = new DefaultMonetaryAmountFormat(context);
MonetaryAmount parsedAmount = format.parse("0.01 USD");
assertSame(parsedAmount.getCurrency(), usd);
assertEquals(parsedAmount.getNumber().doubleValueExact(), 0.01D);
assertEquals(parsedAmount.toString(), "USD 0.01");
}请注意,您需要使用set(CurrencyUnit.class, usd)创建上下文。
但是,如果您尝试使用货币符号(例如0.00 ¤ )设置一个模式,那么您将收到一个错误:javax.money.format.MonetaryParseException: Error parsing CurrencyUnit: no input。
我为此创建了一个票据宽松的格式化程序:用数字解析字符串,但不使用货币代码。,请阅读并添加您的意见。
https://stackoverflow.com/questions/36874805
复制相似问题