What is the standard for formatting currency values in JSON?

会有一股神秘感。 提交于 2019-11-28 10:43:15

I don't know if it's the best solution, but what I'm trying now is to just pass values as strings unformatted except for a decimal point, like so:

"amount": "1234.56"

The app could easily parse that (and convert it to double, BigDecimal, int, or whatever method the app developer feels best for floating-point arithmetic). The app would be responsible for formatting the value for display according to locale and currency.

This format could accommodate other currency values, whether highly inflated large numbers, numbers with three digits after the decimal point, numbers with no fractional values at all, etc.

Of course, this would assume the app already knows the locale and currency used (from another call, an app setting, or local device values). If those need to be specified per call, another option would be:

"amount": "1234.56",
"currency": "USD",
"locale": "en_US"

I'm tempted to roll these into one JSON object, but a JSON feed may have multiple amounts for different purposes, and then would only need to specify currency settings once. Of course, if it could vary for each amount listed, then it would be best to encapsulate them together, like so:

{
"amount": "1234.56",
"currency": "USD",
"locale": "en_US"
}

Another debatable approach is for the server to provide the raw amount and the formatted amount. (If so, I would suggest encapsulating it as an object, instead of having multiple properties in a feed that all define the same concept):

{
"displayAmount":"$1,234.56",
"calculationAmount":"1234.56"
}

Here, more of the work is offloaded to the server. It also ensures consistency across different platforms and apps in how the numbers are displayed, while still providing an easily parseable value for conditional testing and the like.

However, it does leave a problem--what if the app needs to perform calculations and then show the results to the user? It will still need to format the number for display. Might as well go with the first example at the top of this answer and give the app control over the formatting.

Those are my thoughts, at least. I've been unable to find any solid best practices or research in this area, so I welcome better solutions or potential pitfalls I haven't pointed out.

Paul Coldrey

AFAIK, there is no "currency" standard in JSON - it is a standard based on rudimentary types. Things you might want to consider is that some currencies do not have a decimal part (Guinean Franc, Indonesian Rupiah) and some can be divided into thousandths (Bahraini Dinar)- hence you don't want to assume two decimal places. For Iranian Real $2million is not going to get you far so I would expect you need to deal with doubles not integers. If you are looking for a general international model then you will need a currency code as countries with hyperinflation often change currencies every year of two to divide the value by 1,000,000 (or 100 mill). Historically Brazil and Iran have both done this, I think.

If you need a reference for currency codes (and a bit of other good information) then take a look here: https://gist.github.com/Fluidbyte/2973986

ON Dev Portal - API Guidelines - Currencies you may find interesting suggestions :

"price" : {
 "amount": 40,
 "currency": "EUR"
}

It's a bit harder to produce & format than just a string, but I feel this is the cleanest and meaningful way to achieve it :

  1. uncouple amount and currency
  2. use number JSON type

Here the JSON format suggested: https://pattern.yaas.io/v2/schema-monetary-amount.json

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "title": "Monetary Amount",
    "description":"Schema defining monetary amount in given currency.",
    "properties": {
        "amount": {
            "type": "number",
            "description": "The amount in the specified currency"
        },
        "currency": {
            "type": "string",
            "pattern": "^[a-zA-Z]{3}$",
            "description": "ISO 4217 currency code, e.g.: USD, EUR, CHF"
        }
    },
    "required": [
        "amount",
        "currency"
    ]
}

Another questions related to currency format pointed out right or wrongly, that the practice is much more like a string with base units :

{
    "price": "40.0"
}

Amount of money should be represented as string.

The idea of using string is that any client that consumes the json should parse it into decimal type such as BigDecimal to avoid floating point imprecision.

However it would only be meaningful if any part of the system avoids floating point too. Even if the backend is only passing data and not doing any calculation, using floating point would eventually result in what you see (in the program) is not what you get (on the json).

And assuming that the source is a database, it is important to have the data stored with right type. If the data is already stored as floating point then any subsequent conversion or casting would be meaningless as it would technically be passing imprecision around.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!