Je comprends que BigDecimal est la meilleure pratique recommandée pour représenter les valeurs monétaires en Java. Qu'est ce que tu utilises? Y a-t-il une meilleure bibliothèque que vous préférez utiliser à la place?
Je comprends que BigDecimal est la meilleure pratique recommandée pour représenter les valeurs monétaires en Java. Qu'est ce que tu utilises? Y a-t-il une meilleure bibliothèque que vous préférez utiliser à la place?
Réponses:
BigDecimal
tout le. J'ai entendu parler de certaines personnes créant leur propre Cash
ou des Money
classes qui encapsulent une valeur monétaire avec la monnaie, mais sous la peau, c'est toujours un BigDecimal
, probablement avec des BigDecimal.ROUND_HALF_EVEN
arrondis.
Edit: Comme Don le mentionne dans sa réponse , il existe des projets open source comme timeandmoney , et bien que je les félicite d'avoir essayé d'empêcher les développeurs d'avoir à réinventer la roue, je n'ai tout simplement pas assez de confiance dans une bibliothèque pré-alpha à utiliser. dans un environnement de production. De plus, si vous creusez sous le capot, vous verrez qu'ils l'utilisent BigDecimal
aussi .
Il peut être utile aux personnes arrivant ici par les moteurs de recherche de connaître JodaMoney: http://www.joda.org/joda-money/ .
BigDecimal
sous le capot!
Je n'exprime pas mon opinion ici, mais il y a de très bons arguments contre BigDecimal que quelqu'un devrait probablement jeter:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
Une bibliothèque pratique que j'ai rencontrée plus tôt est la bibliothèque Joda-Money . Une de ses implémentations est en effet basée sur BigDecimal. Il est basé sur la spécification ISO-4217 pour les devises et peut prendre en charge une liste de devises personnalisée (chargée via CVS).
Cette bibliothèque contient un petit nombre de fichiers que l'on peut parcourir rapidement si des modifications sont nécessaires. Joda-Money est publié sous la licence Apache 2.0.
Si vous n'utilisez que des dollars et des cents, j'utiliserais un long (décalé de 2 décimales). Si vous avez besoin de plus de détails, la grande décimale peut être la solution.
Quoi qu'il en soit, j'étendrais probablement la classe pour avoir un .toString () qui utilise le format correct, et comme un endroit pour mettre d'autres méthodes qui pourraient apparaître (pendant longtemps, multiplier et diviser ira de travers si la décimale n'est pas pas ajusté)
De plus, si vous définissez votre propre classe et interface, vous pouvez remplacer l'implémentation à volonté.
BigDecimal
ou une autre représentation en virgule fixe est ce qui est généralement nécessaire pour l'argent.
Les représentations et calculs en virgule flottante ( Double
, Float
) sont inexacts, ce qui conduit à des résultats erronés.
Vous devez être très prudent en ce qui concerne le temps et l'argent.
Lorsque vous travaillez avec de l'argent, j'espère que tout le monde devrait savoir qu'il ne faut jamais utiliser de flotteur ou de double.
Mais je ne suis pas sûr de BigDecimal.
Dans la plupart des cas, tout ira bien si vous gardez simplement une trace des centimes dans un int ou un long. De cette façon, vous ne traitez jamais avec une décimale.
Vous n'affichez que les dollars lorsque vous l'imprimez. Travaillez toujours avec des centimes internes en utilisant des entiers. Cela peut être délicat si vous devez diviser ou utiliser Math.abs ().
Cependant, vous pourriez vous soucier d'un demi-cent, voire d'un centième de cent. Je ne sais pas quelle est la bonne façon de faire cela. Vous devrez peut-être simplement traiter un millième de centimes et utiliser un long. Ou peut-être serez-vous obligé d'utiliser BigDecimal
Je ferais beaucoup plus de lecture à ce sujet, mais ignorez tous ceux qui commencent à parler d'utiliser un flotteur ou un double pour représenter l'argent. Ils demandent juste des ennuis.
Je pense que mon conseil n'est pas complet, alors s'il vous plaît, mettez-y davantage. Vous avez affaire à des types dangereux!
Créer une classe Money est la voie à suivre. En utilisant BigDecimal (ou même un int) en dessous. Ensuite, utilisez la classe Currency pour définir la convention d'arrondi.
Malheureusement, sans surcharger les opérateurs, Java rend assez désagréable la création de tels types de base.
Il y a une meilleure bibliothèque, du temps et de l' argent . IMO, il est de loin supérieur aux bibliothèques fournies par le JDK pour représenter ces 2 concepts.
Certainement pas BigDecimal. Il y a tellement de règles spéciales d'arrondi et de présentation que vous devez vous inquiéter.
Martin Fowler recommande la mise en œuvre d'une classe Money dédiée pour représenter les montants en devises, et qui implémente également des règles de conversion de devises.
Hé, voici un article très intéressant sur BigDecimal, et un exemple illustratif de la raison pour laquelle il est parfois utilisé au lieu de doubles. Tutoriel BigDecimal .
Vous pouvez utiliser la classe DecimalFormat lors de l'affichage final d'une valeur monétaire. Il fournit un support de localisation et est assez extensible.
J'encapsulerais BigDecimal dans la classe Money qui a également une devise, tout comme quelqu'un mentionné ci-dessus. L'important est que vous fassiez une quantité extrême de tests unitaires et surtout si vous travaillez avec des devises différentes. C'est aussi une bonne idée si vous ajoutez un constructeur pratique qui prend une chaîne ou une méthode d'usine qui fait la même chose afin que vous puissiez écrire vos tests quelque chose comme ceci:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
Il y a toujours des contraintes et des spécificités impliquées. Toute personne sans expérience suffisante pour apprécier les problèmes subtils décrits dans l'article suivant devrait sérieusement reconsidérer avant de traiter des données financières réelles:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal est loin d'être la seule représentation correcte ou la seule pièce du puzzle. Dans certaines conditions, l'utilisation d'une classe Money adossée à des cents stockés sous forme d'entier pourrait être suffisante et serait beaucoup plus rapide que BigDecimal. Oui, cela implique l'utilisation de dollars comme monnaie et limite les montants mais de telles contraintes sont parfaitement acceptables pour de nombreux cas d'utilisation et toutes les devises ont de toute façon des cas particuliers d'arrondis et de sous-dénominations, il n'y a donc pas de solution "universelle".