使用Moneta(JavaMoney)JSR354实现自定义MonetaryAmountFormat

dha*_*im2 4 java jsr354

我真的很困惑如何MonetaryAmountFormat使用Moneta JSR-354实现自定义.

我的意图是能够解析两者1.23$3.45作为MonetaryAmounts.

这是我的单元测试:

@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);
}
Run Code Online (Sandbox Code Playgroud)

这是我的班级:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我本来很喜欢的是能够解析bidStr有或没有$使用单一的MonetaryAmountFormat,而是花了很多时间试图找出如何使后$可选,我放弃了.不幸的是,我甚至无法弄清楚如何将其1.23解析为美元.莫内塔扔了一个NullPointerException.我应该用AmountFormatQueryBuilder?设置货币?什么是可以使用AmountFormatQueryBuilder?设置的键?我搜索了文档,但找不到任何地方,除了几个常用键,比如pattern.

Bri*_*ent 6

尝试解析不合格的数字(例如1.23)时,JavaMoney似乎不能正常工作.

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

MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.US);
MonetaryAmount amount = format.parse("USD 1.23");
Run Code Online (Sandbox Code Playgroud)

如果设置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");
Run Code Online (Sandbox Code Playgroud)

这可能是你最接近JavaMoney的地方.

如果你知道你只能从同一种货币得到的数字,你可能会更好别处解析字符串(与regexs或东西),并转换到一致的输入格式,因为(如你发现),你轻松搞定NullPointerException,没有解释,当s JavaMoney不高兴.

至于可用密钥,您可以在常量偷看org.javamoney.moneta.format.AmountFormatParams:pattern,groupingSizes,groupingSeparators.

设置格式时,请务必注意您必须使用通用货币符号:¤.例如,你可能会这样做.set("pattern", "¤#,##0.00").

最后,不是直接使用FastMoneyMoneta RI中的类,而是可以从以下位置解析MonetaryAmountFormat:

// rather than using Monata directly:
MonetaryAmount amount = FastMoney.parse(bidStr, format);

// use the API:
MonetaryAmount amount = format.parse(bidStr);
Run Code Online (Sandbox Code Playgroud)