首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Moneta (JavaMoney) JSR354实现自定义一个JSR354

使用Moneta (JavaMoney) JSR354实现自定义一个JSR354
EN

Stack Overflow用户
提问于 2016-04-26 20:09:58
回答 2查看 2.1K关注 0票数 4

我真的很困惑如何使用MonetaJSR-354实现定制MonetaryAmountFormat

我的意图是能够将1.23$3.45解析为MonetaryAmount

这是我的单元测试:

代码语言:javascript
复制
@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);
}

这是我的班级:

代码语言:javascript
复制
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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-29 22:41:01

当试图解析不合格的数字时,JavaMoney似乎不能很好地工作(如1.23)。

默认情况下,MonetaryAmountFormat希望您提供货币名称(如USD 1.23):

代码语言:javascript
复制
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.US);
MonetaryAmount amount = format.parse("USD 1.23");

如果设置了CurrencyStyle.SYMBOL,则可以按货币名称或符号解析(所以,USD 1.23$3.45):

代码语言:javascript
复制
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上的常量:patterngroupingSizesgroupingSeparators

在设置格式时,必须注意必须使用通用的货币符号¤。例如,您可以执行.set("pattern", "¤#,##0.00")

最后,与其直接使用Moneta中的FastMoney类,不如直接从MonetaryAmountFormat解析

代码语言:javascript
复制
// rather than using Monata directly:
MonetaryAmount amount = FastMoney.parse(bidStr, format);

// use the API:
MonetaryAmount amount = format.parse(bidStr);
票数 8
EN

Stack Overflow用户

发布于 2019-02-17 20:15:50

如果您使用的是自定义格式模式,那么您可以解析字符串,它只包含一个没有货币的数字,但是您应该自己指定预期的货币。下面是一个示例:

代码语言:javascript
复制
@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

我为此创建了一个票据宽松的格式化程序:用数字解析字符串,但不使用货币代码。,请阅读并添加您的意见。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36874805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档