从ISO **数字**货币代码

时间:2017-05-23 11:29:59

标签: java jsr354

考虑到ISO 4217 数字货币代码,我尝试使用正确的格式规则格式化金额。

例如,给定金额99.99和数字代码840,我希望产生一个字符串' USD 99.99'或类似的。

看看JSR 354的实现,似乎我需要先找到合适的货币单位。但是,我似乎无法为此目的撰写有效的CurrencyQuery。

鉴于

CurrencyQuery query = CurrencyQueryBuilder.of().setNumericCodes(840).build();
CurrencyUnit cu = Monetary.getCurrency(query);
MonetaryAmount amount = FastMoney.of(99.99, cu);
System.out.println(MonetaryFormats.getAmountFormat(Locale.ENGLISH).format(amount));

我收到以下例外:

Exception in thread "main" javax.money.MonetaryException: Ambiguous request for CurrencyUnit: CurrencyQuery (
{Query.numericCodes=[840]}), found: [BIF, ARS, DZD, COP, CVE, CHF, HRK, IQD, LAK, XPF, DKK, BAM, ZMK, ITL, XBB, XUA, XPT, BRL, CAD, NZD, SEK, USN, XTS, IEP, SRG, STD, BHD, USS, XAF, AUD, CDF, MTL, QAR, AOA, MGA, TOP, LYD, BOV, ISK, ADP, HTG, IDR, ANG, XXX, BTN, KHR, LTL, KES, INR, MGF, OMR, BEF, EUR, BOB, JPY, XBA, AED, SOS, XPD, SKK, FKP, XBC, CRC, SCR, MYR, MZN, LVL, GYD, XDR, GHS, XCD, MDL, MRO, ZWN, LSL, PEN, ATS, XOF, AZM, BYB, TRY, SRD, TTD, IRR, NOK, BZD, TRL, BDT, KZT, CLF, SLL, USD, ETB, BSD, SDD, UYU, ESP, VEB, TMM, CUP, NAD, DOP, NPR, TJS, VND, ZWR, AMD, FRF, TWD, LUF, GNF, MOP, MKD, JMD, CZK, PTE, LBP, ZWD, RSD, FIM, AZN, SDG, GHC, THB, MMK, BBD, PLN, ROL, NGN, RON, TZS, ERN, GBP, TPE, UZS, XBD, SGD, MXV, SVC, FJD, GWP, CNY, BYR, RUB, CSD, XAG, HKD, BND, SHP, KPW, CLP, KYD, DJF, ILS, RUR, LRD, SYP, SAR, ZWL, VUV, DEM, XSU, SIT, PHP, PYG, TND, HNL, ZAR, XFO, BMD, MWK, ZMW, UGX, NLG, JOD, KWD, YER, GMD, CUC, BGL, RWF, UAH, MVR, AWG, MZM, LKR, CYP, VEF, BWP, MXN, KRW, TMT, GIP, MUR, MNT, EEK, GTQ, PKR, PAB, KGS, GRD, YUM, SZL, GEL, WST, MAD, EGP, SBD, ALL, PGK, NIO, AFA, BGN, XAU, SSP, AFN, HUF, XFU, AYM, KMF]

我该如何撰写货币查询?还有更好的方法吗?

TestCurrencyQuery.java

package test;

import java.util.Locale;

import javax.money.CurrencyQuery;
import javax.money.CurrencyQueryBuilder;
import javax.money.CurrencyUnit;
import javax.money.Monetary;
import javax.money.MonetaryAmount;
import javax.money.format.MonetaryFormats;

import org.javamoney.moneta.FastMoney;

public class TestCurrencyQuery {
  public static void main(String[] args) {
    System.out.println(System.getProperty("java.vm.name"));
    System.out.println(System.getProperty("java.version"));
    System.out.println(System.getProperty("java.specification.vendor"));

    CurrencyQuery query = CurrencyQueryBuilder.of().setNumericCodes(840).build();
    CurrencyUnit cu = Monetary.getCurrency(query);
    MonetaryAmount amount = FastMoney.of(99.99, cu);
    System.out.println(MonetaryFormats.getAmountFormat(Locale.ENGLISH).format(amount));
  }
}

的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>test</groupId>
  <artifactId>test-jsr354</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <properties>
   <maven.compiler.source>1.8</maven.compiler.source>
   <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
        <groupId>org.javamoney</groupId>
        <artifactId>moneta</artifactId>
        <version>1.1</version>
    </dependency>
  </dependencies>
</project>

控制台输出

Java HotSpot(TM) 64-Bit Server VM
1.8.0_31
Oracle Corporation
Exception in thread "main" javax.money.MonetaryException: Ambiguous request for CurrencyUnit: CurrencyQuery (
{Query.numericCodes=[840]}), found: [KHR, RON, XTS, FJD, LRD, MVR, BRL, ZMK, PKR, LBP, LYD, SDG, MXV, AED, XDR, STD, CDF, QAR, ISK, SHP, CSD, FRF, BMD, PTE, PLN, XUA, UYU, GYD, LAK, ZAR, ZMW, MKD, XSU, XAF, EEK, ILS, UGX, ITL, XPT, ROL, MUR, INR, TWD, KES, FIM, CHF, HNL, ARS, BGL, KRW, SBD, PHP, RUR, PYG, SRD, AWG, MXN, MGA, SGD, TRL, MZN, SOS, MOP, XBA, IRR, CZK, XFU, TRY, UZS, XFO, TTD, SDD, SCR, COP, ALL, XAU, SYP, USN, PAB, CUC, JMD, GNF, BHD, ANG, IDR, GWP, DEM, SLL, SVC, HRK, NLG, TMT, KZT, MTL, CUP, VEF, ZWN, NOK, LVL, CLF, TMM, BEF, VEB, MZM, DOP, GHS, BBD, XPF, CYP, UAH, BAM, TPE, BND, BYB, MGF, SIT, BWP, XBD, XCD, LSL, AYM, RUB, ADP, SEK, YUM, AOA, WST, GBP, ZWD, THB, ZWL, ESP, MAD, USS, ETB, NGN, AUD, TZS, XAG, VND, BTN, JOD, PGK, XBB, DKK, VUV, BYR, NZD, EGP, SSP, KMF, CNY, MWK, AZM, SAR, CVE, HUF, HTG, SRG, AZN, GIP, LUF, DJF, GEL, RWF, TJS, TOP, TND, ERN, OMR, GRD, MMK, LKR, FKP, NIO, ATS, KPW, PEN, AMD, IEP, BZD, XXX, BIF, GTQ, KYD, EUR, LTL, CRC, HKD, BGN, RSD, SZL, USD, KWD, CLP, MYR, BOB, AFA, GHC, JPY, AFN, GMD, MDL, IQD, BSD, MNT, NPR, MRO, XPD, DZD, NAD, CAD, BOV, KGS, ZWR, SKK, XOF, YER, BDT, XBC]
    at javax.money.spi.MonetaryCurrenciesSingletonSpi.getCurrency(MonetaryCurrenciesSingletonSpi.java:173)
    at javax.money.Monetary.getCurrency(Monetary.java:506)
    at test.TestCurrencyQuery.main(TestCurrencyQuery.java:21)

2 个答案:

答案 0 :(得分:1)

根据moneta的注释,货币只能通过货币代码或区域设置访问。此实现不提供按数字代码访问。以下是按货币代码USD:

访问的方法
CurrencyQuery query = CurrencyQueryBuilder.of().setCurrencyCodes("USD").build();
CurrencyUnit cu = Monetary.getCurrency(query);
MonetaryAmount amount = FastMoney.of(99.99, cu);
System.out.println(MonetaryFormats.getAmountFormat(Locale.ENGLISH).format(amount));

如果您想根据数字代码提交查询,我建议您与项目本身联系。

或者,您可以使用getCurrencies()检索所有货币,并根据数字代码进行过滤:

CurrencyUnit cu = Monetary.getCurrencies().stream()
                .filter(c -> c.getNumericCode() == 840)
                .findAny()
                .orElseThrow(RuntimeException::new);

最后,你可以implement your own CurrencyProvider实现getCurrency基于数字代码进行搜索。

答案 1 :(得分:0)

如前所述,您无法使用此实现通过货币代码访问CurrencyUnit。 如果您的任务严格接受货币代码作为参数,则可以创建自己的映射。更好的方法是使用数据库,您可以在其中存储数字代码和货币代码之间的映射。

package test;

import java.util.Locale;

import javax.money.CurrencyQuery;
import javax.money.CurrencyQueryBuilder;
import javax.money.CurrencyUnit;
import javax.money.Monetary;
import javax.money.MonetaryAmount;
import javax.money.format.MonetaryFormats;

import org.javamoney.moneta.FastMoney;

public class TestCurrencyQuery {
  public static void main(String[] args) {
    System.out.println(System.getProperty("java.vm.name"));
    System.out.println(System.getProperty("java.version"));
    System.out.println(System.getProperty("java.specification.vendor"));

    CurrencyQuery query = CurrencyQueryBuilder.of().setCurrencyCodes(getCurrencyCodesFromNumeric(840)).build();
    CurrencyUnit cu = Monetary.getCurrency(query);
    MonetaryAmount amount = FastMoney.of(99.99, cu);
    System.out.println(MonetaryFormats.getAmountFormat(Locale.ENGLISH).format(amount));
  }

    public String[] getCurrencyCodesFromNumeric(int... codes) {
        Collection<String> currencyCodes = // query db and return associated String currency codes;
        return currencyCodes.toArray(new String[currencyCodes.size()]);
    }
}