Java Money és a Valuta API

1. Áttekintés

JSR 354 - A „Pénznem és pénz” a devizák és a monetáris összegek Java-szabványosításával foglalkozik.

Célja, hogy rugalmas és bővíthető API-t adjon a Java ökoszisztémához, és egyszerűbbé és biztonságosabbá tegye a pénzzel való munkát.

A JSR nem jutott be a JDK 9-be, de a JDK jövőbeli kiadásainak jelöltje.

2. Beállítás

Először határozzuk meg a függőséget pom.xml fájl:

 org.javamoney moneta 1.1 

A függőség legfrissebb verziója itt ellenőrizhető.

3. JSR-354 Jellemzők

A „Pénznem és pénz” API céljai:

  • API biztosítása a pénzösszegek kezeléséhez és kiszámításához
  • A pénznemeket és monetáris összegeket, valamint a monetáris kerekítést képviselő osztályok meghatározása
  • Valutaárfolyamokkal foglalkozni
  • Valuták és monetáris összegek formázásával és elemzésével foglalkozni

4. Modell

A JSR-354 specifikáció fő osztályait a következő ábra mutatja:

A modell két fő interfészt tartalmaz CurrencyUnit és MonetaryAmount, magyarázza a következő szakaszokban.

5. CurrencyUnit

CurrencyUnit modellezi a valuta minimális tulajdonságait. Példányai a Monetary.getCurrency módszer:

@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); }

Mi alkotunk CurrencyUnit használva Húr a pénznem ábrázolása, ez olyan helyzethez vezethet, amikor nem létező kóddal próbálunk pénznemet létrehozni. A nem létező kódokkal rendelkező pénznemek létrehozása egy Ismeretlen pénznem kivétel:

@Test (várható = IsmeretlenCurrencyException.class) public void givenCurrencyCode_whenNoExist_thanThrowsError () {Monetary.getCurrency ("AAA"); } 

6. MonetaryAmount

MonetaryAmount egy monetáris összeg numerikus ábrázolása. Mindig a CurrencyUnit és meghatározza a valuta monetáris képviseletét.

Az összeg különböző módon valósítható meg, összpontosítva a monetáris reprezentációs követelmények viselkedésére, amelyet az egyes konkrét felhasználási esetek határoznak meg. Például. Pénz és FastMoney megvalósításai MonetaryAmount felület.

FastMoney megvalósítja MonetaryAmount felhasználásával hosszú numerikus ábrázolásként, és gyorsabb, mint BigDecimal pontosság árán; akkor használható, ha teljesítményre van szükségünk, és a pontosság nem kérdés.

Általános példány létrehozható az alapértelmezett gyár használatával. Mutassuk meg a megszerzés más módját MonetaryAmount példányok:

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

7. Monetáris számtan

Között végezhetünk monetáris számtant Pénz és FastMoney de óvatosnak kell lennünk, amikor e két osztály példányait egyesítjük.

Például, ha összehasonlítjuk az euró egyik példányát FastMoney egy euró példánnyal Pénz az eredmény az, hogy nem azonosak:

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

Összeadási, kivonási, szorzási, osztási és egyéb monetáris számtani műveleteket hajthatunk végre a MonetaryAmount osztály.

A számtani műveleteknek egy Számtani kivétel, ha az összegek közötti számtani műveletek felülmúlják az alkalmazott numerikus ábrázolási típus képességeit, például ha megpróbálunk felosztani háromra, akkor egy Számtani kivétel mert az eredmény végtelen szám:

@Test (várható = ArithmeticException.class) public void givenAmount_whenDivided_thanThrowsException () {MonetaryAmount oneDolar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); oneDolar.divide (3); }

Összegek összeadásakor vagy kivonásakor jobb olyan paramétereket használni, amelyek példányai MonetaryAmount, mivel biztosítanunk kell, hogy mindkét összegnek ugyanaz a pénzneme legyen az összegek közötti műveletek végrehajtásához.

7.1. Összegek kiszámítása

Az összegek többféleképpen is kiszámíthatók, az egyik mód egyszerűen az összegek láncolása a következőkkel:

@Test public void givenAmounts_whenSummed_thanCorrect () {MonetaryAmount [] MonetAmounts = new MonetaryAmount [] {Money.of (100, "CHF"), Money.of (10.20, "CHF"), Money.of (1.15, "CHF") }; PénzösszegAmtCHF = Pénz.of (0, "CHF"); for (MonetaryAmount monetárisAmount: monetárisAmounts) {összegAmtCHF = összegAmtCHF.add (monetárisösszeg); } assertEquals ("CHF 111,35", sumAmtCHF.toString ()); }

A láncolás kivonásra is alkalmazható:

Pénz calcAmtUSD = Money.of (1, "USD"). Kivonás (fstAmtUSD); 

Szorzás:

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

Vagy osztva:

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

Hasonlítsuk össze aritmetikai eredményeinket a Strings segítségével, mivel ez a Strings-szel, mert az eredmény a pénznemet is tartalmazza:

@Test public void givenArithmetic_whenStringified_thanEqualsAmount () {CurrencyUnit usd = Monetary.getCurrency ("USD"); Money moneyof = Money.of (12, usd); MonetaryAmount fstAmtUSD = Monetary.getDefaultAmountFactory () .setCurrency (usd) .setNumber (200.50) .create (); MonetaryAmount oneDolar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); Money subtractedAmount = Money.of (1, "USD"). Kivonás (fstAmtUSD); MonetaryAmount multiplyAmount = oneDolar.multiply (0,25); MonetaryAmount divideAmount = oneDolar.divide (0,25); assertEquals ("USD", usd.toString ()); assertEquals ("USD 1", oneDolar.toString ()); assertEquals ("USD 200,5", fstAmtUSD.toString ()); assertEquals ("USD 12", moneyof.toString ()); assertEquals ("-199,5 USD", kivonvaAmount.toString ()); assertEquals ("0,25 USD", multiplyAmount.toString ()); assertEquals ("USD 4", divideAmount.toString ()); }

8. Monetáris kerekítés

A monetáris kerekítés nem más, mint egy meghatározatlan pontosságú összegből átszámított összegre történő átszámítás.

Használjuk a getDefaultRounding Az API által biztosított Pénzügyi osztály az átalakítás elvégzéséhez. Az alapértelmezett kerekítési értékeket a pénznem adja meg:

@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. Pénzváltás

A valutaátváltás fontos szempont a pénz kezelésében. Sajnos ezeknek a konverzióknak nagyon sokféle megvalósítása és felhasználási esete van.

Az API a pénznem konverziójának általános szempontjaira összpontosít, a forrás, a célvaluta és az árfolyam alapján.

A valutaváltás vagy az árfolyamokhoz való hozzáférés paraméterezhető:

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

Az átváltás mindig a valutához kötött. MonetaryAmount egyszerűen konvertálható az a átadásával CurrencyConversion összegéhez val vel módszer.

10. Pénznem formázása

A formázás lehetővé teszi az alapú formátumok elérését java.util.Locale. A JDK-val ellentétben az ezen API által meghatározott formázók szálbiztosak:

@Test public void givenLocale_whenFormatted_thanEquals () {MonetaryAmount oneDollar = Monetary.getDefaultAmountFactory () .setCurrency ("USD"). SetNumber (1) .create (); MonetaryAmountFormat formatUSD = MonetaryFormats.getAmountFormat (Locale.US); String usFormatted = formatUSD.format (oneDollar); assertEquals ("USD 1", oneDollar.toString ()); assertNotNull (formatUSD); assertEquals ("USD1.00", usFormatted); }

Itt az előre definiált formátumot használjuk, és létrehozunk egy egyedi formátumot a pénznemünkhöz. A szabványos formátum használata egyszerű a .metód formátum használatával MonetaryFormats osztály. Meghatároztuk egyéni formátumunkat, beállítva a formátum lekérdezés készítő mintatulajdonságát.

Mint korábban, mivel a pénznem szerepel az eredményben, az eredményeinket felhasználva teszteljük Húrok:

@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 ()); String customFormatted = customFormat.format (oneDollar); assertNotNull (customFormat); assertEquals ("USD 1", oneDollar.toString ()); assertEquals ("00001,00 amerikai dollár", customFormatted); }

11. Összegzés

Ebben a rövid cikkben a Java Money & Currency JSR alapjait ismertettük.

A monetáris értékeket mindenhol használják, és a Java biztosítja, hogy kezdi támogatni és kezelni a monetáris értékeket, a számtani vagy valutaátváltásokat.

Mint mindig, a cikket is megtalálhatja a Githubon.