Java Money and the Currency API

1. Prehľad

JSR 354 - „Mena a peniaze“ sa zaoberá štandardizáciou mien a peňažných čiastok v prostredí Java.

Jeho cieľom je pridať flexibilné a rozšíriteľné API do ekosystému Java a zjednodušiť a zabezpečiť prácu s peňažnými sumami.

JSR sa nedostali do JDK 9, ale je kandidátom na budúce vydania JDK.

2. Inštalácia

Najskôr si definujme závislosť na našu pom.xml spis:

 org.javamoney moneta 1.1 

Najnovšiu verziu závislosti si môžete skontrolovať tu.

3. Funkcie JSR-354

Ciele API „Mena a peniaze“:

  • Poskytnúť API na spracovanie a výpočet peňažných súm
  • Definovať triedy predstavujúce meny a peňažné sumy, ako aj menové zaokrúhľovanie
  • Zaoberať sa výmennými kurzami mien
  • Zaoberať sa formátovaním a analýzou mien a peňažných čiastok

4. Model

Hlavné triedy špecifikácie JSR-354 sú zobrazené v nasledujúcom diagrame:

Model obsahuje dve hlavné rozhrania CurrencyUnit a MonetaryAmount, vysvetlené v nasledujúcich častiach.

5. CurrencyUnit

CurrencyUnit modeluje minimálne vlastnosti meny. Jeho inštancie je možné získať pomocou Monetary.getCurrency metóda:

@Test public void givenCurrencyCode_whenString_thanExist () {CurrencyUnit usd = Monetary.getCurrency ("USD"); assertNotNull (usd); assertEquals (usd.getCurrencyCode (), "USD"); assertEquals (usd.getNumericCode (), 840); assertEquals (usd.getDefaultFractionDigits (), 2); }

Tvoríme CurrencyUnit pomocou a String reprezentácia meny, mohlo by to viesť k situácii, keď sa pokúsime vytvoriť menu s neexistujúcim kódom. Vytváranie mien s neexistujúcimi kódmi zvyšuje Neznáma mena výnimka:

@Test (očakáva sa = UnknownCurrencyException.class) public void givenCurrencyCode_whenNoExist_thanThrowsError () {Monetary.getCurrency ("AAA"); } 

6. MonetaryAmount

MonetaryAmount je číselné vyjadrenie peňažnej sumy. Vždy je to spojené s CurrencyUnit a definuje peňažné zastúpenie meny.

Sumu je možné implementovať rôznymi spôsobmi so zameraním na správanie sa požiadaviek na peňažné zastúpenie, ktoré sú definované v jednotlivých konkrétnych prípadoch použitia. Napríklad. Peniaze a FastMoney sú implementácie MonetaryAmount rozhranie.

FastMoney náradie MonetaryAmount použitím dlho ako číselné vyjadrenie a je rýchlejší ako BigDecimal za cenu presnosti; dá sa použiť, keď potrebujeme výkon a presnosť nie je problém.

Generickú inštanciu je možné vytvoriť pomocou predvolenej továrne. Ukážme si iný spôsob získania MonetaryAmount prípady:

@Test public void givenAmounts_whenStringified_thanEquals () {CurrencyUnit usd = Monetary.getCurrency ("USD"); MonetaryAmount fstAmtUSD = Monetary.getDefaultAmountFactory () .setCurrency (usd) .setNumber (200) .create (); Peniaze moneyof = Money.of (12, usd); FastMoney fastmoneyof = FastMoney.of (2, usd); assertEquals ("USD", usd.toString ()); assertEquals ("200 USD", fstAmtUSD.toString ()); assertEquals ("12 USD", moneyof.toString ()); assertEquals ("2,00000 USD", fastmoneyof.toString ()); }

7. Menová aritmetika

Môžeme vykonávať menovú aritmetiku medzi Peniaze a FastMoney ale musíme byť opatrní, keď kombinujeme inštancie týchto dvoch tried.

Napríklad, keď porovnávame jednu inštanciu eura v hodnote FastMoney s jednou inštanciou eura v Peniaze výsledkom je, že nie sú rovnaké:

@Test public void givenCurrencies_whenCompared_thanNotequal () {MonetaryAmount oneDolar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); Peniaze oneEuro = Money.of (1, „EUR“); assertFalse (oneEuro.equals (FastMoney.of (1, "EUR"))); assertTrue (oneDolar.equals (Money.of (1; „USD“))); }

Môžeme vykonávať operácie sčítania, odčítania, násobenia, delenia a ďalšie peňažné aritmetické operácie pomocou metód poskytovaných metódou MonetaryAmount trieda.

Aritmetické operácie by mali hádzať Aritmetická výnimka, ak aritmetické operácie medzi množstvami prekonajú možnosti použitého typu numerického znázornenia, napríklad ak sa pokúsime rozdeliť jednu na tri, dostaneme Aritmetická výnimka pretože výsledkom je nekonečné číslo:

@Test (očakáva sa = ArithmeticException.class) public void givenAmount_whenDivided_thanThrowsException () {MonetaryAmount oneDolar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); oneDolar.divide (3); }

Pri sčítaní alebo odčítaní súm je lepšie použiť parametre, ktoré sú inštanciami MonetaryAmount, pretože potrebujeme zabezpečiť, aby obe sumy mali rovnakú menu na vykonávanie operácií medzi čiastkami.

7.1. Výpočet súm

Celkovú sumu je možné vypočítať viacerými spôsobmi, jedným spôsobom je jednoducho reťaziť sumy pomocou:

@Test public void givenAmounts_whenSummed_thanCorrect () {MonetaryAmount []etaryAmounts = new MonetaryAmount [] {Money.of (100, "CHF"), Money.of (10.20, "CHF"), Money.of (1.15, "CHF") }; Peniaze sumAmtCHF = Money.of (0, "CHF"); pre (MonetaryAmountetaryAmount: financialAmUNTY) {sumAmtCHF = sumAmtCHF.add (financialAmount); } assertEquals ("111,35 CHF", sumAmtCHF.toString ()); }

Reťazenie je možné použiť aj na odpočítanie:

Peniaze calcAmtUSD = Money.of (1, "USD"). Odpočítať (fstAmtUSD); 

Násobenie:

MonetaryAmount multiplyAmount = oneDolar.multiply (0,25);

Alebo delenie:

MonetaryAmount divideAmount = oneDolar.divide (0,25);

Porovnajme naše aritmetické výsledky pomocou reťazcov, pretože s reťazcami, pretože výsledok obsahuje aj menu:

@Test public void givenArithmetic_whenStringified_thanEqualsAmount () {CurrencyUnit usd = Monetary.getCurrency ("USD"); Peniaze moneyof = Money.of (12, usd); MonetaryAmount fstAmtUSD = Monetary.getDefaultAmountFactory () .setCurrency (usd) .setNumber (200,50) .create (); MonetaryAmount oneDolar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); Peniaze subtractedAmount = Money.of (1; „USD“). Odpočítať (fstAmtUSD); MonetaryAmount multiplyAmount = oneDolar.multiply (0,25); MonetaryAmount divideAmount = oneDolar.divide (0,25); assertEquals ("USD", usd.toString ()); assertEquals ("1 USD", oneDolar.toString ()); assertEquals ("200,5 USD", fstAmtUSD.toString ()); assertEquals ("12 USD", moneyof.toString ()); assertEquals ("USD -199,5", subtractedAmount.toString ()); assertEquals ("0,25 USD", multiplyAmount.toString ()); assertEquals ("4 USD", divideAmount.toString ()); }

8. Menové zaokrúhľovanie

Peňažné zaokrúhľovanie nie je nič iné ako prevod z čiastky s neurčenou presnosťou na zaokrúhlenú čiastku.

Použijeme getDefaultRounding API poskytované Peňažné triedy na prevedenie. Predvolené hodnoty zaokrúhľovania sú poskytované menou:

@Test public void givenAmount_whenRounded_thanEquals () {MonetaryAmount fstAmtEUR = Monetary.getDefaultAmountFactory () .setCurrency ("EUR"). SetNumber (1,30473908) .create (); MonetaryAmount roundEUR = fstAmtEUR.with (Monetary.getDefaultRounding ()); assertEquals ("1,30473908 EUR", fstAmtEUR.toString ()); assertEquals ("1,3 EUR", roundEUR.toString ()); }

9. Prepočet mien

Prepočet meny je dôležitým aspektom zaobchádzania s peniazmi. Tieto konverzie majú, bohužiaľ, veľké množstvo rôznych implementácií a prípadov použitia.

API sa zameriava na bežné aspekty prepočtu mien na základe zdrojovej, cieľovej meny a výmenného kurzu.

Prepočet mien alebo prístup k výmenným kurzom je možné parametrizovať:

@ Test public void givenAmount_whenConversion_thenNotNull () {MonetaryAmount oneDollar = Monetary.getDefaultAmountFactory (). SetCurrency ("USD") .setNumber (1) .create (); CurrencyConversion conversionEUR = MonetaryConversions.getConversion ("EUR"); MonetaryAmount convertedAmountUSDtoEUR = oneDollar.with (conversionEUR); assertEquals ("1 USD", oneDollar.toString ()); assertNotNull (convertedAmountUSDtoEUR); }

Prepočet je vždy viazaný na menu. MonetaryAmount možno jednoducho konvertovať zložením a Prepočet meny na sumu s metóda.

10. Formátovanie meny

Formátovanie umožňuje prístup k formátom založeným na java.util.Locale. Na rozdiel od JDK sú formátory definované týmto API bezpečné pre vlákna:

@Test public void givenLocale_whenFormatted_thanEquals () {MonetaryAmount oneDollar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); Formát MonetaryAmountFormatUSD = MonetaryFormats.getAmountFormat (Locale.US); Reťazec usFormatted = formatUSD.format (oneDollar); assertEquals ("1 USD", oneDollar.toString ()); assertNotNull (formatUSD); assertEquals ("1,00 USD", usFormatted); }

Tu používame preddefinovaný formát a vytvárame vlastný formát pre naše meny. Používanie štandardného formátu je priame pomocou formátu metódy formátu MonetaryFormats trieda. Definovali sme naše vlastné nastavenie formátu, ktoré nastavuje vlastnosť vzoru v nástroji na tvorbu formátovacích dotazov.

Rovnako ako predtým, pretože vo výsledku je zahrnutá mena, testujeme naše výsledky pomocou Struny:

@Test public void givenAmount_whenCustomFormat_thanEquals () {MonetaryAmount oneDollar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); MonetaryAmountFormat customFormat = MonetaryFormats.getAmountFormat (AmountFormatQueryBuilder. Of (Locale.US) .set (CurrencyStyle.NAME) .set ("pattern", "00000.00 ¤"). Build ()); Reťazec customFormatted = customFormat.format (oneDollar); assertNotNull (customFormat); assertEquals ("1 USD", oneDollar.toString ()); assertEquals ("00001,00 americký dolár", customFormatted); }

11. Zhrnutie

V tomto rýchlom článku sme sa venovali základom Java Money & Currency JSR.

Peňažné hodnoty sa používajú všade a program Java poskytuje podporu a spracovanie peňažných hodnôt, aritmetické výpočty alebo prepočty mien.

Ako vždy, kód z článku nájdete na Githube.


$config[zx-auto] not found$config[zx-overlay] not found