Quel est le standard pour la mise en forme de la valeur des devises en JSON?
En gardant à l'esprit les diverses bizarreries des types de données, et de la localisation, quelle est la meilleure façon pour un service web pour communiquer les valeurs monétaires et d'applications? Est-il un standard quelque part?
Ma première pensée a été d'utiliser simplement le type de numéro. Par exemple
"amount": 1234.56
J'ai vu beaucoup d'arguments sur les questions avec un manque de précision et les erreurs d'arrondi lors de l'utilisation de données à virgule flottante types de calculs monétaires--cependant, nous sommes juste à la transmission de la valeur, pas de calcul, de sorte que ne devrait pas d'importance.
EventBrite JSON monnaie spécifications spécifier quelque chose comme ceci:
{
"currency": "USD",
"value": 432,
"display": "$4.32"
}
Bravo pour éviter les valeurs à virgule flottante, mais maintenant nous avons un autre problème: quel est le plus grand nombre, on peut tenir?
Un commentaire (Je ne sais pas si c'est vrai, mais il semble raisonnable) affirme que, depuis nombre d'implémentations varient en JSON, le meilleur que vous pouvez vous attendre est un entier signé 32 bits. La plus grande valeur d'un entier signé 32 bits peut contenir 2 147 483 647. Si nous représentons les valeurs dans l'unité secondaire, c'est $21,474,836.47. 21 millions de dollars semble comme un grand nombre, mais il n'est pas inconcevable que certaines applications peuvent avoir besoin de travailler avec une valeur plus grande que celle. Le problème s'aggrave avec les monnaies où 1 000 de l'unité secondaire de faire une grande unité, ou lorsque la monnaie vaut moins que le dollar US. Par exemple, un Dinar Tunisien est divisé en 1000 milim. 2147483647 milim, ou 2147483.647 TND est $1,124,492.04. C'est encore plus susceptibles que les valeurs supérieures à 1 million de dollars peut être travaillée dans certains cas. Un autre exemple: les sous-unités de la dong Vietnamien ont été rendus inutiles par l'inflation, donc, nous allons simplement utiliser de grandes unités. 2147483647 VND est $98,526.55. Je suis sûr que beaucoup de cas d'utilisation (les soldes bancaires, les valeurs des biens immobiliers, etc.) sont nettement plus élevés que cela. (EventBrite probablement ne pas avoir à vous soucier du prix des billets étant très élevé, si!)
Si nous éviter ce problème, par la communication de la valeur sous forme de chaîne de caractères, comment la chaîne d'être formaté? Les différents pays/paramètres régionaux ont radicalement différents formats, différents symboles de devise, si le symbole a lieu avant ou après la quantité, si oui ou non il y a un espace entre le symbole et le montant, si une virgule ou un point est utilisé pour séparer les décimales, si les virgules sont utilisés comme séparateur de milliers, des parenthèses ou un signe pour indiquer les valeurs négatives, et peut-être plus que je ne suis pas au courant.
Devrait l'application de savoir ce qu'locale/de la monnaie, c'est travailler avec, de véhiculer des valeurs comme
"amount": "1234.56"
d'avant en arrière, et faire confiance à l'app pour formater correctement la quantité? (Aussi: si la valeur décimale être évitée, et la valeur spécifiée dans les termes de la plus petite unité monétaire? Ou si le majeur et mineur de l'unité de l'être présentés dans les différentes propriétés?)
Ou si le serveur de fournir de la valeur brute et la valeur formatée?
"amount": "1234.56"
"displayAmount": "$1,234.56"
Ou si le serveur de fournir de la valeur brute et le code de la devise, et laisser l'application formater?
"montant": "1234.56"
"currencyCode": "USD"
Je suppose que soit la méthode utilisée devrait être utilisé dans les deux directions, la transmission de vers et depuis le serveur.
J'ai été incapable de trouver le standard--avez-vous une réponse, ou peut m'indiquer une ressource qui la définit? Il semble comme un problème commun.
- Question connexe: stackoverflow.com/questions/45222706/...
Vous devez vous connecter pour publier un commentaire.
Je ne sais pas si c'est la meilleure solution, mais ce que j'essaie maintenant est de transmettre des valeurs comme des chaînes de caractères non formaté à l'exception d'une virgule, comme ceci:
L'application peut analyser facilement que (et le convertir en double, BigDecimal, int, ou quelle que soit la méthode le développeur de l'application se sent le mieux pour l'arithmétique à virgule flottante). L'application serait responsable de la mise en forme de la valeur pour l'affichage en fonction du lieu et de la monnaie.
Ce format pourrait accueillir d'autres devises, et si fortement gonflé les grands nombres, les nombres à trois chiffres après la virgule, des numéros avec aucune des valeurs fractionnaires à tous, etc.
Bien sûr, cela suppose l'application sait déjà les paramètres régionaux et la devise utilisée (à partir d'un autre appel, une application de configuration, ou locale de l'appareil les valeurs). Si ceux qui ont besoin d'être précisées par appel, une autre option serait:
Je suis tenté de rouler dans un objet JSON, mais un flux JSON peut avoir plusieurs montants pour différentes raisons, et puis il ne serait nécessaire de spécifier les paramètres de devise, une fois. Bien sûr, si elle peut varier pour chaque montant indiqué, alors il serait la meilleure pour encapsuler ensemble, comme suit:
Une autre approche est discutable pour le serveur pour fournir le montant brut et de la mise en forme des montant. (Si si, je vous suggère d'encapsulation comme un objet, au lieu d'avoir plusieurs propriétés dans un flux qui définissent tous le même concept):
Ici, plus le travail est déchargé pour le serveur. Il s'assure également de la cohérence à travers différentes plates-formes et les applications dans la façon dont les numéros sont affichés, tout en fournissant un facilement parseable valeur conditionnelle pour les essais et la comme.
Cependant, elle laisse un problème: que faire si l'application a besoin pour effectuer des calculs et de montrer ensuite les résultats à l'utilisateur? Il sera toujours nécessaire de formater le nombre à l'affichage. Pourrait tout aussi bien aller avec le premier exemple en haut de cette réponse et de l'application de contrôle sur le formatage.
Ce sont mes pensées, au moins. J'ai été incapable de trouver une solide meilleures pratiques ou de recherche dans ce domaine, donc je souhaite la bienvenue à de meilleures solutions ou des pièges potentiels, je n'ai pas souligné.
Autant que je sache, il n'y a pas de "monnaie" standard en JSON - c'est un standard basé sur rudimentaires types. Choses que vous pourriez envisager est que certaines monnaies n'ont pas de partie décimale (Franc Guinéen, la Roupie Indonésienne), et certains peuvent même être divisée en millièmes (Dinar de Bahreïn)- donc, vous ne voulez pas assumer deux décimales. Iranien Réel de 2 millions de dollars ne va pas loin, c'est pourquoi je m'attends à ce que vous devrez traiter avec des doubles pas des entiers. Si vous êtes à la recherche pour un modèle international, alors vous aurez besoin d'un code de la devise du pays à l'hyperinflation souvent changer des devises chaque année de deux à diviser la valeur par 1 000 000 (ou 100 mill). Historiquement, le Brésil et l'Iran ont tous deux fait ce, je pense.
Si vous avez besoin d'une référence pour les codes des monnaies (et un peu d'autres bonnes informations), puis prendre un coup d'oeil ici: https://gist.github.com/Fluidbyte/2973986
SUR Dev Portail de l'API, les Directives sur les Monnaies vous pouvez trouver des suggestions intéressantes :
C'est un peu plus difficile de produire un & format que juste une chaîne de caractères, mais j'ai l'impression que c'est le plus propre et de manière significative à atteindre :
number
JSON
typeIci le format JSON suggéré:
https://pattern.yaas.io/v2/schema-monetary-amount.json
Un autre les questions liées à la monnaie format souligné droit ou à tort, que la pratique est beaucoup plus comme une chaîne avec des unités de base :
Somme d'argent devrait être représenté comme une chaîne de caractères.
L'idée d'utiliser la chaîne, c'est que tout client qui consomme le json doit l'analyser en décimal type comme
BigDecimal
pour éviter de virgule flottante de l'imprécision.Cependant, il aurait de sens que si une partie quelconque du système évite à virgule flottante trop. Même si le backend est seulement la transmission des données et ne fais pas de calcul, à l'aide de virgule flottante serait éventuellement aboutir à ce que vous voyez (dans le programme) n'est pas ce que vous obtenez (sur le json).
Et en supposant que la source est une base de données, il est important d'avoir les données stockées avec le bon type. Si les données sont déjà stockées flottant, alors toute conversion ou de l'incantation pas de sens car il serait techniquement passant imprécision autour de.