Sunday, 23 August 2009

Joda-Money

I've been busy piloting a new open source project - Joda-Money. The idea is a simple money and currency package along the lines of Joda-Time.

Joda-Money

Joda-Money is a new project to try and create a small, focussed monetary library for Java. While there are various libraries that tackle this area, I wanted one that fitted with the Joda-Time style.

So far, I've created a Money and CurrencyUnit class and started on formatting. The goal of the library is only these basic classes. Financial calculations (for whatever domain) or classes storing specific concepts like gross/net/tax are out of scope for the library.

The design is as follows:

Money is the main class, and supports an amount of money with the decimal places determined by the currency. Thus, GBP always has 2 decimal places, while JPY always has 0.

CurrencyUnit is the class representing currency. I debated whether to just use the JDK Currency class, but it doesn't handle currency changes, or provide the numeric code (both being fixed in JDK 7).

MoneyFormatter will provide formatting of Money instances.

BigMoney will be the final class, which will allow any amount of decimal places to be specified for any currency.

This blog is a 'release early' notification. If you like the Javadoc, or think that this is an area that should be tackled, then let me know. If not, then also let me know (I don't want to waste my time...). Lets hear the feedback!

17 comments:

  1. I would take a look at the jscience project. They have some decent classes for handling money, as well as other units (area, length, volume etc)

    ReplyDelete
  2. I'd love to see some capability to deal with the fractional penny/Office Space/Superman III problem. For example, given an amount that I'd like to divide into a number of different buckets with different percentages, make sure each bucket has a non-fractional amount and that the total of the buckets equals the original amount. Martin Fowler has some sample code to deal with this problem, but perhaps it could be extended with different strategies for handling the extra pennies (all in last bucket, all in first, at most one extra penny per bucket, separate accumulator, etc/). It would be nice to be able to accumulate and distribute extra pennies across multiple operations (e.g. calculating tax charges across a number of paychecks), although I'm at a loss to figure out how that might work.

    ReplyDelete
  3. I'm totally in. Please add a getHtmlEntity() to return €, $, etc.

    ReplyDelete
  4. Artur Biesiadowski24 August 2009 at 11:02

    Can you describe what kind of application do you have in mind when designing those classes?

    For example, it is quite common in finance world to get below cent/eurocent detail level in prices for some things (derivatives, commodities). In some cases it is size dependent (for example, go to tenths of eurocent if price is below 0.10 EUR, full eurcents if above).
    US exchange has funny x/8 and x/32 notations (in dollars).
    Currency changing is way more complicated than can be covered by any simple class. For most trivial cases (online calculator for fun) you don't need any special classes, just multiply two doubles. For something more real, you will not have just simple exchange rate - it will vary per quantity for example.

    As I understand, library is mainly aimed at online-shop kind of usage, which simplified currency exchange?

    ReplyDelete
  5. What about non-decimalised currency?

    Are there any currencies left that are non-decimal?

    ReplyDelete
  6. Stephen Colebourne24 August 2009 at 13:52

    @chris, I am aware of JScience, this is a more focussed project.

    @brian, I'm not planning on doing algorithms, but if you or anyone else wanted to build another feel free (hosted here or elsewhere).

    @ignacio, Interesting idea.

    @ntdaley, According to wikipedia, two currencies are divided into 5 subunits. I plan on dealing with this by marking them as 10 subunits (which while not accurate, is compatible).

    BTW, anyone should feel free to join the mailing list to discuss things further.

    ReplyDelete
  7. Stephen Colebourne24 August 2009 at 13:56

    @Artur, Yes, Money is complicated. While the basic Money class will have fixed decimal place, BigMoney will be as controllable as a BigDecimal. Of course that won't handle 1/8 or 1/32, but you can never tackle every use case in a single library. Overall, the library is intended for code I write (scratch my itch) - if its more generally useful, then good ;-)

    ReplyDelete
  8. If you want to deal with derivatives, a scaled long (as used by Money) may be inadequate. The (pre crash) Gross World Product as about 1e14 US$, while the total of outstanding derivatives was much larger.

    With regard to algorithms, I think one of the more common queries with BigDecimal is how to calculate mortage payments. Inexplicably the answer of converting to double to solve the problem doesn't find favour! ;-)

    ReplyDelete
  9. mortage ==> mortgage
    Where is my proof reader ...

    ReplyDelete
  10. Stephen Colebourne24 August 2009 at 16:12

    @Mark, thats what BigMoney will be used for ;-)

    ReplyDelete
  11. class DerivativeValue extends BigMoney implements Nonsense {
    ...
    }

    ;-))

    ReplyDelete
  12. Does this mean you've completed jsr310 (date-and-time for JDK7)? Or has that simply lost your interest?

    ReplyDelete
  13. Sometimes a fresh slate is best, but you might scan timeandmoney.sf.net--it has a Money class that we enjoyed using. It also solved the penny problem, though had a slight bug in its implementation, IIRC.

    ReplyDelete
  14. Thanks for the hint on that other SF project.
    Not that I had not mentioned that once myself, but all Eric Evans ever did is to make "money" with DDD books and presentations, but he just like other luminaries sadly failed to get that into any proper API (and so have all the people who read his books, at least on a really reusable or SDK level ;-)

    Glad to hear it also works for some cases, so using it as a discussion basis beside all the other options is what I'll do with the JCP EC in 10 days.

    Some of those are beside JSR-275 (which I'm one of the 2 Spec Leads of, I also kept the issue in discussion with Stephen among others) and JodaMoney:
    - ICU4J (also embedded with Eclipse but fairly unknown and mostly used internally)
    - Eclipse Financial / OFMP - so far both failed attempts of a vertical financial market project in the style of Eclipse OHF or STEM
    - Grails Currency Plugin - a pretty good and small extension using java.util.Currency, but adding Money and a small time-based ExchangeRate Manager. This is not complete but has potential.

    Beside that is an approach similar to JSR-275/JScience with a base currency for conversions in the commercial product MoneyDance. Not Open Source, but the API is well documented and also has some potential in its underlying ideas.

    While a Exchange Rate Management tool may almost exceed the scope of such library/JSR, I believe that and some basic feeds for common sites like Yahoo or Google Financial should be part of at least an RI for this, too. So we are basically talking about a JSR that has partial overlaps both with 310 (at least on the customized Calendar front, especially knowing Business Days from Bank Holidays could be vital ;-) and 275 but should first of all extend and possibly replace java.util.Currency.

    ReplyDelete
  15. @Stephen one more thing to consider at least when formatting money is, that multipliers/prefixes recently added to JSR-275 like Crore and Lakh are used extensively with Money values.

    And this by no less than 1-2 Billion people, namingly all of India, Pakistan, Bangladesh and a few smaller neighbours like Burma, etc.

    JodaTime already has a couple of local calendars, so JodaMoney or similar APIs should ultimately also respect those countries and cultures.

    ReplyDelete
  16. > Does this mean you've completed jsr310 (date-and-time for JDK7)? Or has that simply lost your interest?

    Perhaps you read this differently, but I read it as if Stephen has open sourced a library he build and uses internally for the company that pays his salary.

    ReplyDelete
  17. Always nice to see this sort of thing. I was hoping to open source the one at my company, but it's a big company and open sourcing code is not a trivial process.

    I do have one question about the usefulness of the "Money" class as it is described. Surely if you do any non-trivial calculations at all, it is not very useful? I just wonder whether it justifies it's existence... Or perhaps it is useful given the overhead of BigMoney?

    The way we solved the penny problem was to have a Money that has an internal BigDecimal, which high-precision and have a method resolve() which takes the money value to a real valid currency amount (is also automatically done by our formatter).

    BTW, I found this document extemely helpful when designing our Money library: http://www.objectivelogic.com/resources/Java%20and%20Monetary%20Data/Java%20and%20Monetary%20Data.pdf

    Now, if only you could specify operators as methods in Java... (our Scala money code is sooo much more readable)

    ReplyDelete