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 BigDecimal class. 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. http://joda-money.sourceforge.net/ (a Java library, current release is 0.7)
  2. http://www.thomasknierim.com/114/scala/scala-currency-class/ (not on Github or Sourceforge, but you can download source from the author's site)
  3. 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.

And just as quick, 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:

Scala money/currency - Summary

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

If you already have experience in deal with money and currency in Scala, I'd be glad to hear your thoughts. Just leave a note in the Comments section below.

Add new comment

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.