Skip to content

Commit d44c71e

Browse files
Move Money Module in from source repo
1 parent 8d99b6d commit d44c71e

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

javax-money/MONEY.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Representing Money in JSON
2+
3+
> 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.
4+
>
5+
> [Martin Fowler](https://martinfowler.com/eaaCatalog/money.html)
6+
7+
Unfortunately JSON is no different. This document tries to change that by proposing and comparing different styles to represent money, some inspired by external sources and some based on our own experience.
8+
9+
## ⚠️ Monetary amounts ≠ floats
10+
11+
Before we dive into details, always keep the following in mind. However you desire to format money in JSON, nothing changes the fact that you should...
12+
13+
> **Never hold monetary values [..] in a float variable.** Floating point is not suitable for this work, and you must use either [fixed-point](#fixed-point) or [decimal](#decimal) values.
14+
>
15+
> [Coinkite: Common Terms and Data Objects](https://web.archive.org/web/20150924073850/https://docs.coinkite.com/api/common.html)
16+
17+
## Styles
18+
19+
We identified the following styles that all of different advantages and disadvantages that are discussed in their respective section.
20+
21+
| Style | Expressive | Arithmetic | Pitfalls / Misuses |
22+
|------------------------------------|------------|------------|--------------------|
23+
| [Decimal](#decimal) ||| Precision |
24+
| [Quoted Decimal](#quoted-decimal) ||| Parsing |
25+
| [Fixed Point](#fixed-point) ||| Mixed scales |
26+
| [Mixed](#mixed) ||| Consistency |
27+
28+
### Decimal
29+
30+
The most straightforward way to represent a monetary amount would be a base-10 decimal number:
31+
32+
```json
33+
{
34+
"amount": 49.95,
35+
"currency": "EUR"
36+
}
37+
```
38+
39+
It's expressive, readable and allows arithmetic operations. The downside is that most [JSON decoders will treat it as a floating point](https://tools.ietf.org/html/rfc7159#section-6) number which is very much undesirable.
40+
41+
Most programming languages have support for arbitrary-precision [decimals](#decimal-implementations) and JSON decoders that can be configured to use them. In general it can be considered to be a problem of the implementation, not the format itself.
42+
43+
### Quoted Decimal
44+
45+
Same as [Decimal](#decimal) but quoted so your JSON decoder treats it as a string:
46+
47+
```json
48+
{
49+
"amount": "49.95",
50+
"currency": "EUR"
51+
}
52+
```
53+
54+
It solves the precision problem of decimals on the expense of performing arithmetic operations on it. It also requires a two-phase parsing, i.e. parsing the JSON text into a data structure and then parsing quoted amounts into decimals.
55+
56+
### Fixed Point
57+
58+
> A value of a fixed-point data type is essentially an integer that is scaled by an implicit specific factor determined by the type.
59+
>
60+
> [Wikipedia: Fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic)
61+
62+
```json
63+
{
64+
"amount": 4995,
65+
"currency": "EUR"
66+
}
67+
```
68+
69+
The implicit scaling factor is defined as (0.1 raised to the power of) the currency's [default number of fraction digits](http://www.localeplanet.com/icu/currency.html).
70+
71+
In rare cases one might need a higher precision, e.g. to have sub-cent. In this case the scale can be defined explicitly:
72+
73+
```json
74+
{
75+
"amount": 499599,
76+
"currency": "EUR",
77+
"scale": 4
78+
}
79+
```
80+
81+
The downside with fixed-point amounts is that reading them is a bit harder and arithmetic with mixed scale amounts can be tricky and error-prone.
82+
83+
### Mixed
84+
85+
As a way to counter all negative aspects of the styles above one idea would be to have a single object that contains all of the formats:
86+
87+
```json
88+
{
89+
"decimal": 49.95,
90+
"quoted_decimal": "49.95",
91+
"fixed_point": 4995,
92+
"scale": 2,
93+
"currency": "EUR"
94+
}
95+
```
96+
97+
Decoders can choose the representation that fits them the best. Encoders on the other hand have the harder task by providing all of them and making sure that all values are in fact consistent.
98+
99+
## Decimal Implementations
100+
101+
| Language | Implementation |
102+
|------------|---------------------------------------------------------------------------------------------|
103+
| C# | [decimal](https://msdn.microsoft.com/en-us/library/364x0z75.aspx) |
104+
| Java | [java.math.BigDecimal](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html) |
105+
| JavaScript | [decimal.js](https://github.com/MikeMcl/decimal.js/) |
106+
| Python | [decimal.Decimal](https://docs.python.org/2/library/decimal.html) |
107+
108+
## Credits and References
109+
110+
- [Coinkite: Currency Amounts](https://web.archive.org/web/20150924073850/https://docs.coinkite.com/api/common.html#currency-amounts)
111+
- [Culttt: How to handle money and currency in web applications](http://culttt.com/2014/05/28/handle-money-currency-web-applications/)
112+
- [Currency codes - ISO 4217](https://www.iso.org/iso-4217-currency-codes.html)
113+
- [LocalePlanet: ICU Currencies](http://www.localeplanet.com/icu/currency.html)
114+
- [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159#section-6)
115+
- [Stackoverflow: What is the standard for formatting currency values in JSON?](http://stackoverflow.com/questions/30249406/what-is-the-standard-for-formatting-currency-values-in-json)
116+
- [Stackoverflow: Why not use Double or Float to represent currency?](http://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency/3730040#3730040)
117+
- [TechEmpower: Mangling JSON numbers](https://www.techempower.com/blog/2016/07/05/mangling-json-numbers/)
118+
- [Wikipedia: Fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic)

javax-money/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ deserialization of [JavaMoney](https://github.com/JavaMoney/jsr354-api) data typ
55
integrates JavaMoney and Jackson so that they work seamlessly together, without requiring additional
66
developer effort. In doing so, it aims to perform a small but repetitive task — once and for all.
77

8+
This library reflects an opinionated API [representation of monetary amounts in JSON](MONEY.md)
9+
810
With this library, it is possible to represent monetary amounts in JSON as follows:
911

1012
```json

0 commit comments

Comments
 (0)