Scala money and currency: The BigDecimal class and libraries

(Note: I don't have any immediate solutions in this article; it's more of a discussion of where I'm at today when looking at handling money/currency in Scala.)

As a quick note, I've started to look at handling money/currency in Scala, and I'm also starting to explore a couple of money/currency libraries.

The BigDecimal class

As a bit of background, almost everyone handles currency with the Scala BigDecimal class, though I have also heard other people say that they use the Double type. There's a bit more to it than that, as described in this "Representing Money" article, but it usually comes down to BigDecimal.

Joda Money and other currency libraries

The most promising Scala money/currency libraries I've found are listed here:

  1. Update: I have more Scala money/currency library links on this page
  2. http://joda-money.sourceforge.net/ (a Java library, current release is 0.7)
  3. http://www.thomasknierim.com/114/scala/scala-currency-class/ (not on Github or Sourceforge, but you can download source from the author's site)
  4. http://timeandmoney.sourceforge.net/ ("need alpha users")

Frankly, I'd only use the last two links if the Joda Money library didn't work. I don't remember the specific problems, but the unit tests for the second link won't compile under Scala 2.9, and as the author states, the code is a little "monolithic". That being said, if nothing else existed, I'd use his code base as a starting point for my own library. The "need alpha users" on the third link scared me off right away, though again, if nothing else existed, I'd take a harder look at their code.

So at this point it's down to working with currency in Scala using either a) the Joda Money library or b) just using the BigDecimal class. The things that concern me about Joda Money are the 0.7 release, and the lack of interaction on their discussion forum.

BigDecimal problems and solutions

I don't have time to get into all the details today, but here's a quick example of a problem with using the BigDecimal class to handle money:

scala> val salary = 100000: BigDecimal
salary: BigDecimal = 100000

scala> val weekly = salary / 52
weekly: scala.math.BigDecimal = 1923.076923076923076923076923076923

scala> val biWeekly = salary / 26
biWeekly: scala.math.BigDecimal = 3846.153846153846153846153846153846

As you can see, the weekly and biWeekly salary numbers run off there for a while, so you always need to do something to deal with rounding issues.

Depending on your needs, here's the beginning of a solution to that problem:

scala> import scala.math.BigDecimal.RoundingMode
import scala.math.BigDecimal.RoundingMode

scala> weekly.setScale(2, RoundingMode.HALF_EVEN)
res0: scala.math.BigDecimal = 1923.08

The following URL shows how to do a few things with BigDecimal and MathContext:

  • http://www.scala-lang.org/node/7115

This URL has a few discussions about how to use BigDecimal with currency:

Summary: Scala money/currency

I'm sorry that I'm not much help today; as mentioned, I'm just beginning to head down this road.