Weitere ähnliche Inhalte Ähnlich wie Money, Money, Money, can be funny with JSR 354 (DWX 2019) (20) Mehr von Werner Keil (20) Kürzlich hochgeladen (20) Money, Money, Money, can be funny with JSR 354 (DWX 2019)2. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Who am I?
Werner Keil
• Consultant – Coach
• Creative Cosmopolitan
• Open Source Evangelist
• Software Architect
• Spec Lead – JSR 385
• Maintenance Lead – JSR 354
[www.linkedin.com/in/catmedia]
Twitter @wernerkeil
3. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Who am I?
Anatole Tresch
• Consultant – Coach
• Software Architect
• Fitness Enthusiast
• Open Source Evangelist
• Trivadis AG
• Maintenance Lead – JSR 354
[www.linkedin.com/in/anatoletresch]
Twitter @atsticks
4. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Agenda
1. History and Motivation
2. Currencies and Amounts
3. Precision and Rounding
4. Currency Conversion
5. Demos
6. Roadmap
5. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
History and Motivation
6. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Motivation
Monetary values are a key feature to many applications
Existing java.util.Currency class is strictly a structure used for
representing ISO-4217 standard currencies.
No standard value type to represent a monetary amount
No support for currency arithmetic or conversion
JDK Formatting features lack flexibility
7. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Earlier Approaches
Martin Fowler:
A large proportion of the computers in this
world manipulate money, so it’s always
puzzled me that money isn’t actually a
first class data type in any mainstream
programming language. The lack of a
type causes problems, the most obvious
surrounding currencies…
see
http://martinfowler.com/eaaCatalog/mone
y.html
Eric Evans – Time and Money:
On project after project, software developers
have to reinvent the wheel, creating objects for
simple recurring concepts such as “money” and
“currency”. Although most languages have a
“date” or “time” object, these are rudimentary,
and do not cover many needs, such as recurring
sequences of time, durations of time, or intervals
of time. …
To be quite frank, their code isn’t more than an
academic POC, factories called dollars() or
euros() are useless in real globally deployed
frameworks, but he made a good point.
9. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
9
Challenges
Keep it simple
Remember the most common use case
Performance
How to support low latency applications, such as High Frequency
Trading
Precision
Differing precisions for arithmetic, currency exchange and formatting
10. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
10
Challenges (2)
Formatting
Reuse existing Number Formats, where possible.
BUT...
...Indian Rupees might look something like this:
12,34,00,000
11. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
11
Challenges (3)
Natural language formatting:
For example Lakhs, Crores:
1 Lakh = 100,000
1 Crore = 100 Lakh
12,34,56,000.21
=
12 Crore, 34 Lakh, 56 Thousand Rupees and 21 Paise
Non-standard rounding modes
12. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
12
Challenges (4)
Non-standard rounding modes
It is a big world, and each country has its regulations and
cultural nuances for expressing currencies in natural language,
rounding policies, groupings, etc.
For example, in Argentina rounding is prescribed for the third digit
after the decimal point.
14. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Adding JSR 354 to your project
<dependency>
<groupId>org.javamoney</groupId>
<artifactId>moneta-core</artifactId>
<version>1.3</version>
</dependency>
15. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Overview of JSR 354
Core API: javax.money
CurrencyUnit, MonetaryAmount and exceptions
Conversion API: javax.money.convert
ExchangeRate, ConversionContext, CurrencyConversion
Formatting: javax.money.format
AmountFormatContext, MonetaryAmountFormat
Extensions: javax.money.spi
CurrencyProvider, RoundingProvider, ServiceProvider,…
Reference Implementation: org.javamoney.moneta
TCK: org.javamoney.tck
16. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Currencies and Amounts
javax.money
17. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Currencies
ISO 4217
Special Codes
Ambiguities
Unmodeled
Aspects
Minor units
• Precious Metals (XAU, XAG)
• Testing (XTS)
• No Currency (XXX)
• Supranational currencies, e.g. East Caribbean dollar,
the CFP franc, the CFA franc.
• CFA franc: West African CFA franc und Central African CFA
franc = denotes 2 effectively interchangeable (!).
• Switzerland: CHF, CHE (WIR-EURO), CHW (WIR)
• USA: USD, USN (next day), USS (same day)
Legal acceptance, e.g. Indian Rupees are legally accepted in
Bhutan/Nepal, but not vice versa!
Typically 1/100, rarely 1/1000, but also 1/5
(Mauritania, Madagascar), 0.00000001 (Bitcoin)
18. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Video Game Currencies (Gold, Gil, Rupees, Credits, Gold Rings, Hearts, Zenny,
Potch, Munny, Nuyen…)
Facebook Libra, a new virtual currency you can use to buy
virtual goods in any games or apps of the Facebook
platform that accept payments. Facebook also
plans to use Libra for money transfer similar to
Western Union, MoneyGram or others.
Scrutiny by regulators and some countries
like China won’t allow it at all
Bitcoin (sign: BTC) is a decentralized digital currency
based on an open-source, peer-to-peer internet protocol.
It was introduced by a pseudonymous developer named
Satoshi Nakamoto in 2009. Hundreds of “Altcoins” followed
Virtual Currencies
19. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Improve java.util.Currency
Limitations of java.util.Currency:
• No historical Currencies
• No non standard Currencies
(e.g. cows or camels)
• No virtual Currencies
• No support for custom
schemes (e.g. legacy codes)
• Only access by currency
code, or Locale
• No support for special use
cases/extensions
Implementation:
BuildableCurrencyUnit
public interface CurrencyUnit{
public String getCurrencyCode();
public int getNumericCode();
public int getDefaultFractionDigits();
// new methods
public CurrencyContext getContext();
}
20. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Access/Create Currencies
Usage
/**
* Shows simple creation of a CurrencyUnit for ISO, backed by JDK
* Currency implementation.
*/
public void forISOCurrencies() {
CurrencyUnit currency = Monetary.getCurrency("USD"); // backed up util.Currency!
currency = Monetary.getCurrency("myCode", "myProvider");
}
21. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Amount = Number + Currency + Operations ?
Challenge: Contradictory requirements!
• Performance (e.g. for trading)
• Precision and Scale (e.g. for calculations)
• Must model small numbers (e.g. web shop)
• Must support large Numbers (e.g. risk calculations, statistics)
• Rounding
• Financial Operations and Functions, function chaining
How to represent the numeric amount?
-> Multiple numeric representations!
-> Exendability by MonetaryFunction & MonetaryOperator
Monetary Amount
22. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Monetary Amount (continued)
public interface MonetaryAmount{
public CurrencyUnit getCurrency();
public Class<?> getNumberType();
public <T> T asType(Class<T>);
public int intValue(); public int intValueExact();
public long longValue(); public long longValueExact();
[…]
public MonetaryAmount abs();
public MonetaryAmount min(…);
public MonetaryAmount max(…);
public MonetaryAmount add(…);
public MonetaryAmount substract(…);
public MonetaryAmount divide(…);
public MonetaryAmount[] divideAndRemainder(…);
public MonetaryAmount divideToIntegralValue(…);
public MonetaryAmount remainder(…);
public MonetaryAmount multiply(…);
public MonetaryAmount withAmount(Number amount);
[…]
public int getScale(); public int getPrecision();
[…]
public boolean isPositive(); public boolean isPositiveOrZero();
public boolean isNegative(); public boolean isNegativeOrZero();
public boolean isLessThan(…);
public boolean isLessThanOrEqualTo(…);
[…]
public MonetaryAmount with(MonetaryOperator op); }
Algorithmic Operations…
Data Representation and
Comparison.
Data Access.
Implementation:
Money
23. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Monetary Function, Operator
//@FunctionalInterface for Java 9
public interface MonetaryFunction<T, R> {
public R apply(T value);
}
Implementations:
MinorPart
MajorPart
Reciprocal
MonetaryRounding
CurrencyConversion
//@FunctionalInterface for Java 9
public interface MonetaryOperator
extends
MonetaryFunction<MonetaryAmount,MonetaryAmount> {
}
Implementations:
Minimum
Maximum
Average
SeparateAmount
SeparateCurrencies
Total
23 © 2007-2012 Creative Arts & Technologies
24. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
/**
* Simplest case create an amount with an ISO currency.
*/
public void forISOCurrencies() {
MonetaryAmount amount = Money.of(1234566.15, "USD"); // using ISO by default
}
/**
* Create an amount using a custom currency.
*/
public void forCustomCurrencies() {
CurrencyUnit currency = Monetary.getCurrency("myCode");
MonetaryAmount amount = Money.of(1234566.15, currency);
}
24
Creating Amounts
25. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Precision and Rounding
javax.money
26. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Numeric Precision
• Internal Precision (implied by internal number type)
• External Precision (Rounding applied, when the numeric part is
accessed/passed outside)
• Formatting Precision (Rounding for display and output)
• Interoperability
• Different precision/scale
• Distinct numeric representations
• Serialization
-> only internal rounding is applied automatically.
-> The precision/scale capabilities of an MonetaryAmount are inherited
to its operational results.
27. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Rounding
• External Rounding and Formatting Rounding depends on use case
• Rounding is modeled as a MonetaryOperator
Example for non standard-rounding: Argentina
• If the third digit is 2 or less,
change it to 0 or drop it.
• If the third digit is between 3
and 7, change it to 5.
• If the third digit is 8 or more, add one to
the second digit and drop the third digit or
change it to 0.
Original Rounded Remark
123.452 123.45 3. digit <3 -> round down
123.456 123.455 3<= 3. digit <=7 -> change to 5
123.459 123.46 3. digit >=8 -> round up
Implementation:
MoneyRounding
28. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Currency Conversion
javax.money.convert
29. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Currency Conversion
• ExchangeRateType
• ExchangeRate:
• ConversionContext
• Base, Term currency
• Conversion factor
• Direct/Derived Rates
• MonetaryConversions accessor singleton
public interface ExchangeRate {
public CurrencyUnit getBaseCurrency();
public CurrencyUnit getCurrency();
public NumberValue getFactor();
public ConversionContext getContext();
public List<ExchangeRate> getExchangeRateChain();
public boolean isDerived();
}
29
30. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Currency Conversion
// Get a compound provider
ExchangeRateProvider provider = MonetaryConversions.getExchangeRateProvider();
CurrencyConversion currencyConversion = provider
.getCurrencyConversion(“BRL”); // BRAZILIAN_REAL
Money usDollars = Money.of(100, “USD”);
Money brasilianReals = currencyConversion.apply(usDollars);
// Get an explicit provider, access historic rate
ExchangeRateProvider ecbProvider = MonetaryConversions.getExchangeRateProvider(
ExchangeRateType.ECB_HIST.get());
LocalDate localDate = YearMonth.of(2014, Month.JANUARY).atDay(9);
ConversionQuery conversionQuery = ConversionQueryBuilder.of()
.setTermCurrency(“USD”).set(localDate).build();
CurrencyConversion currencyConversion = provider
.getCurrencyConversion(conversionQuery);
Money euros = Money.of(100, “EUR”);
Money usDollars = currencyConversion.apply(euros);
30
31. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Adopters
Zalando
31
Image: Zalando
33. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Roadmap
• Embracing Java 8 features
• Further support of JSR 310 (Date & Time) types
• Type Annotations (if appropriate)
• Use of Lambdas where appropriate
• Alignment with Java 9+ features
• Modular environment - While the API should be backward-compatible with at least Java SE 8, both
API and RI are expected to expose Java 9 modules
• Multi-release JAR files - This should allow a single API and RI to support Java 8, 9 and further
versions where beneficial.
• Bean Validation Support
• Value Types if available by the underlying platform
34. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Roadmap (2)
• Use the Jakarta Config, (ex 382) or equivalent for configuration
• Polyglot language support
• Support for dynamic currency/token types
• query to server or blockchain, e.g. for Ethereum ERC-20, Omni, Colored Coins, etc.
• Hierarchical currency types
• e.g. ETH.EOS or OMNI.TETHER
• Support for Open Banking and Payment standards
• PSD2 or the W3C Payment Request API
• See https://github.com/JavaMoney/jsr354-api/issues
35. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Schedule
• Countries and currencies keep changing, from North Macedonia to
South Sudan, or others like Italy and Greece are sometimes
rumored to leave the Euro zone and go back to their old
currencies,…
• JCP 2.11 (JSR 387) introduced Iterative JSRs, which we consider
using when proposing a new Money JSR.
• Allowing to spread a single JSR across multiple project releases
without having to file a new JSR each time.
36. © 2012-2019 JavaMoney project and others. All rights reserved.#DWX #JavaMoney @jsr354
Links
JavaMoney: http://javamoney.org
JSR 354 Twitter Account: @jsr354
JSR detail page on JCP.org: https://www.jcp.org/en/jsr/detail?id=354
JavaMoney on GitHub: https://github.com/JavaMoney
JavaMoney on Groups.io: https://javamoney.groups.io