it-swarm.com.de

Darstellung von Geldwerten in Java

Ich verstehe, dass BigDecimal empfohlen wird, um Geldwerte in Java darzustellen. Was benutzt du? Gibt es eine bessere Bibliothek, die Sie lieber verwenden?

91
dshaw

BigDecimal den ganzen Weg. Ich habe von einigen Leuten gehört, die ihre eigenen Cash oder Money Klassen erstellen, die einen Barwert mit der Währung verkapseln, aber unter dem Strich ist es immer noch ein BigDecimal, wahrscheinlich mit - BigDecimal.ROUND_HALF_EVEN Rundung.

Bearbeiten: Wie Don in seine Antwort erwähnt, gibt es Open-Source-Projekte wie Zeit und Geld und Ich begrüße sie, dass sie versuchen, Entwickler daran zu hindern, das Rad neu zu erfinden, aber ich habe nicht genug Vertrauen in eine Pre-Alpha-Bibliothek, um sie in einer Produktionsumgebung zu verwenden. Außerdem, wenn Sie unter der Motorhaube herumgraben, sehen Sie sie verwenden auch BigDecimal .

76
ninesided

Personen, die über Suchmaschinen anreisen, können sich über JodaMoney informieren: http://www.joda.org/joda-money/ .

50

Ich drücke hier meine Meinung nicht aus, aber es gibt ziemlich gute Argumente gegen BigDecimal, die wahrscheinlich jemand rausschmeißen sollte:

http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/

14
orbfish

Eine praktische Bibliothek, auf die ich früher gestoßen bin, ist die Joda-Money Bibliothek. Eine seiner Implementierungen basiert in der Tat auf BigDecimal. Es basiert auf der ISO-4217 Spezifikation für Währungen und kann eine benutzerdefinierte Währungsliste (geladen über CVS) unterstützen.

Diese Bibliothek enthält eine kleine Anzahl von Dateien, die bei Änderungen schnell durchsucht werden können. Joda-Money wird unter der Apache 2.0-Lizenz veröffentlicht.

8
Bashar

Wenn Sie nur Dollar und Cent verwenden, würde ich ein Long verwenden (um 2 Dezimalstellen versetzt). Wenn Sie mehr Details benötigen, kann eine große Dezimalstelle der richtige Weg sein.

In beiden Fällen würde ich die Klasse wahrscheinlich erweitern, um eine .toString () zu haben, die das richtige Format verwendet, und um andere Methoden zu platzieren, die möglicherweise auftauchen (Multiplizieren und Dividieren wird lange Zeit schief gehen, wenn die Dezimalstelle nicht stimmt nicht angepasst)

Wenn Sie Ihre eigene Klasse und Schnittstelle definieren, können Sie die Implementierung auch nach Belieben ersetzen.

7
Bill K

BigDecimal oder eine andere Festkommadarstellung wird im Allgemeinen für Geld benötigt.

Gleitkommadarstellungen (Double, Float) und Berechnungen sind ungenau und führen zu fehlerhaften Ergebnissen.

3
Ken Gentle

Es gibt eine bessere Bibliothek, Zeit und Geld . IMO, es ist den vom JDK zur Verfügung gestellten Bibliotheken bei der Darstellung dieser beiden Konzepte weit überlegen.

2
Dónal

Das Erstellen einer Money-Klasse ist der richtige Weg. Verwenden Sie BigDecimal (oder sogar ein Int) darunter. Verwenden Sie anschließend die Währungsklasse, um die Rundungskonvention zu definieren.

Leider macht es ohne Überladung des Operators Java) ziemlich unangenehm, solche Grundtypen zu erstellen.

2
Kozyarchuk

Mit Zeit und Geld muss man so vorsichtig umgehen.

Wenn Sie mit Geld arbeiten, hoffe ich, dass jeder wissen sollte, dass er niemals einen Float oder ein Double benutzen sollte.

Bei BigDecimal bin ich mir jedoch nicht sicher.

In den meisten Fällen geht es Ihnen gut, wenn Sie nur die Cents in einem int oder long verfolgen. Auf diese Weise haben Sie es nie mit einer Dezimalstelle zu tun.

Sie zeigen nur Dollars an, wenn Sie es drucken. Arbeiten Sie immer mit Cents intern mit ganzen Zahlen. Dies kann schwierig sein, wenn geteilt oder Math.abs () verwendet werden muss.

Es könnte Sie jedoch interessieren, ob Sie einen halben Cent oder sogar einen Hundertstel Cent verdienen. Ich weiß nicht, wie das gut geht. Möglicherweise müssen Sie nur mit Tausendstel Cent umgehen und eine lange verwenden. Oder Sie müssen BigDecimal verwenden

Ich würde viel mehr darüber lesen, aber jeden ignorieren, der anfängt, ein Float oder Double zu verwenden, um Geld darzustellen. Sie bitten nur um Ärger.

Ich habe das Gefühl, mein Rat ist nicht vollständig. Sie haben es mit gefährlichen Typen zu tun!

2
Pyrolistical

Hey, hier ist ein sehr interessanter Artikel über BigDecimal und ein anschauliches Beispiel, warum es manchmal anstelle von Doubles verwendet wird. BigDecimal Tutorial .

1
arg20

Auf keinen Fall BigDecimal. Es gibt so viele Sonderregeln für das Runden und Präsentieren, dass Sie sich Sorgen machen müssen.

Martin Fowler empfiehlt die Implementierung einer dedizierten Money -Klasse zur Darstellung von Währungsbeträgen und implementiert auch Regeln für die Währungsumrechnung.

1
lindelof

Sie können die DecimalFormat-Klasse verwenden, wenn Sie letztendlich einen Währungswert anzeigen. Es bietet Lokalisierungsunterstützung und ist ziemlich erweiterbar.

0
myanswer

Es gibt immer Einschränkungen und Besonderheiten. Jeder, der nicht über ausreichende Erfahrung verfügt, um die im folgenden Artikel beschriebenen subtilen Probleme zu erkennen, sollte diese ernsthaft überdenken, bevor er sich mit realen Finanzdaten befasst:

http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money

BigDecimal ist kaum die einzig richtige Darstellung oder das einzige Puzzleteil. Unter bestimmten Umständen kann die Verwendung einer Money-Klasse, die durch als Ganzzahl gespeicherte Cents gesichert ist, ausreichend und viel schneller als BigDecimal sein. Ja, dies impliziert die Verwendung von Dollar als Währung und Grenzwerte, aber solche Einschränkungen sind für viele Anwendungsfälle durchaus akzeptabel, und für alle Währungen gibt es ohnehin Sonderfälle für Rundungen und Teilbeträge, sodass es keine "universelle" Lösung gibt.

0
Craig

Ich würde BigDecimal in der Money-Klasse einkapseln, die auch eine Währung hat, genau wie jemand, der oben erwähnt wurde. Wichtig ist, dass Sie extrem viele Unit-Tests durchführen, insbesondere, wenn Sie mit verschiedenen Währungen arbeiten. Es ist auch eine gute Idee, wenn Sie einen praktischen Konstruktor hinzufügen, der eine Zeichenfolge oder eine Factory-Methode verwendet, die dasselbe tut, damit Sie Ihre Tests in etwa so schreiben können:

   assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
0
Per Arneng