Представление валютных ценностей в Java

Я понимаю, что BigDecimal рекомендуется использовать для представления денежных ценностей в Java. Что ты используешь? Есть ли лучшая библиотека, которую вы предпочитаете использовать вместо этого?

Ответ 1

BigDecimal полностью. Я слышал о том, что некоторые люди создают свои собственные классы Cash или Money, которые инкапсулируют денежное значение с помощью валюты, но под кожей это еще BigDecimal, возможно, с BigDecimal.ROUND_HALF_EVEN округление.

Изменить: Как упоминает Дон в его ответ, есть проекты с открытым исходным кодом, такие как timeandmoney, и хотя я приветствую их, пытаясь помешать разработчикам переосмыслить колесо, я просто не уверен в предварительной библиотеке, чтобы использовать ее в производстве Окружающая среда. Кроме того, если вы копаетесь под капотом, вы увидите они используют BigDecimal тоже.

Ответ 2

Может быть полезно людям, прибывающим сюда поисковыми системами, чтобы узнать о JodaMoney: http://www.joda.org/joda-money/.

Ответ 4

Удобная библиотека, с которой я столкнулся раньше, это библиотека Joda-Money. Одна из его реализаций действительно основана на BigDecimal. Он основан на спецификации ISO-4217 для валют и может поддерживать настроенный список валют (загружаемый через CVS).

В этой библиотеке есть небольшое количество файлов, которые можно быстро пройти, если необходимы изменения. Joda-Money публикуется под лицензией Apache 2.0.

Ответ 5

Если вы просто используете доллары и центы, я бы использовал длинный (смещение на 2 десятичных знака). Если вам нужно больше деталей, большой десятичный знак может быть способом.

В любом случае, я бы, вероятно, расширил класс, чтобы иметь .toString(), который использует правильный формат, и как место для размещения других методов, которые могут возникнуть (долгое время, умножение и деление будет ошибочным, если десятичное значение не регулируется)

Кроме того, если вы используете определение собственного класса и интерфейса, вы можете заменить реализацию по своему усмотрению.

Ответ 6

BigDecimal или другое представление с фиксированной точкой - это то, что обычно необходимо для денег.

Плавающая точка (Double, Float) представления и вычисления неточны, что приводит к ошибочным результатам.

Ответ 7

Вы должны быть настолько осторожны, когда имеете дело со временем и деньгами.

Когда вы работаете с деньгами, я надеюсь, что каждый должен знать, никогда не использовать float или double.

Но я не уверен в BigDecimal.

В большинстве случаев вам будет хорошо, если вы просто отслеживаете центы в int или long. Таким образом, вы никогда не имеете дело с десятичной точкой.

При печати вы показываете только доллары. Всегда работайте с внутренними центами, используя целые числа. Это может быть сложно, если необходимо разделить или использовать Math.abs().

Тем не менее, вам может быть полезно получить полцены или даже одну сотую доли процента. Я не знаю, как это сделать. Вам просто нужно иметь дело с тысячной центов и использовать длинный. Или, может быть, вы будете вынуждены использовать BigDecimal

Я бы сделал намного больше чтения об этом, но проигнорировал всех, кто начинает говорить об использовании float или double, чтобы представлять деньги. Они просто просят о неприятностях.

Я чувствую, что мой совет не является полным, поэтому, пожалуйста, добавьте в него больше. Вы имеете дело с опасными типами!

Ответ 8

Создание класса Money - это путь. Использование BigDecimal (или даже int) снизу. Затем используйте класс Currency для определения соглашения округления.

К сожалению, без перегрузки Java Java делает довольно неприятным создание таких базовых типов.

Ответ 9

Существует лучшая библиотека, timeandmoney. IMO, он намного превосходит библиотеки, предоставленные JDK для представления этих двух концепций.

Ответ 10

Определенно не BigDecimal. Существует так много специальных правил округления и представления, о которых вам нужно беспокоиться.

Мартин Фаулер рекомендует внедрить специальный класс Money для представления сумм валют, а также реализует правила конвертации валют.

Ответ 11

Эй, здесь очень интересная статья о BigDecimal, и иллюстративный пример того, почему иногда она используется вместо двухлокальных. Учебник BigDecimal.

Ответ 12

Вы можете использовать класс DecimalFormat, когда в итоге отображается значение валюты. Он обеспечивает поддержку локализации и довольно расширяем.

Ответ 13

Я бы инкапсулировал BigDecimal в класс Money, у которого также есть валюта, как и кто-то, упомянутый выше. Важно то, что вы выполняете экстремальное количество модульных тестов и особенно при работе с разными валютами. Также неплохо, если вы добавите удобный конструктор, который принимает строку или метод factory, который делает то же самое, чтобы вы могли написать свои тесты примерно так:

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

Ответ 14

Всегда существуют ограничения и особенности. Любой, кто не имеет достаточного опыта для понимания тонких вопросов, изложенных в следующей статье, должен серьезно пересмотреть, прежде чем обращаться с реальными финансовыми данными:

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

BigDecimal вряд ли является единственным правильным представлением или единственной частью головоломки. При определенных условиях использование класса Money, поддерживаемого центами, хранящимися как целое число, может быть достаточным и будет намного быстрее, чем BigDecimal. Да, это подразумевает использование долларов в качестве валюты и лимитов, но такие ограничения вполне приемлемы для многих случаев использования, и все валюты имеют особые случаи для округления и субдоменов в любом случае, поэтому нет "универсального" решения.