Java Currency Conversion Class

Commercial applications that aim to provide multi-currency functionality need a currency converter facility with access to up-to-date foreign exchange rates. This is what the CurrencyConverter class offers. Click here to download the CurrencyConverter.java source code.

static CurrencyConverter getInstance()
  Returns a singleton instance of CurrencyConverter.
double convert(double amount, java.lang.String fromCurrency,
java.lang.String toCurrency)
  Converts a double precision floating point value from one
  currency to another.

long convert(long amount, java.lang.String fromCurrency,
java.lang.String toCurrency)
  Converts a long value from one currency to another.

boolean isAvailable(java.lang.String currency)
  Check whether the exchange rate for a given currency is available.

java.lang.String[] getCurrencies()
  Returns all currencies for which exchange rates are available.

java.util.Date getReferenceDate()
  Get the reference date for the exchange rates as a Java Date.

java.lang.String getCacheFileName()
  Get the name of the fully qualified path name of the
  XML cache file.

void setCacheFileName(java.lang.String cacheFileName)
  Set the location where the XML cache file should be stored.

void clearCache()
  Delete XML cache file and reset internal data structure.

The CurrencyConverter class provides an API for accessing the European Central Bank's (ECB) foreign exchange rates. The published ECB rates contain exchange rates for approx. 35 of the world's major currencies. They are updated daily at 14:15 CET. These rates use EUR as reference currency and are specified with a precision of 1/10000 of the currency unit (one hundredth cent). The convert() method performs currency conversions using either double values or 64-bit long integer values. Long values are preferred in order to avoid problems associated with floating point arithmetics. A local cache file is used for storing exchange rates to reduce network latency. The cache file is updated automatically when new exchange rates become available. It is created/updated the first time a call to convert() is made. By calling the clearCache() method before convert(), a reload of the exchange rates from the ECB server is forced. The CurrencyConverter class is implemented as a simple singleton; it is currently not thread-safe. It should be fairly easy to change it into a Java Bean, or to add code for sub-classing. Update Oct-2009: Manish Dubey has extended the CurrencyConverter class to access exchange rates up to 90 days in the past. With this extension, exchange rates for any currency can be retrieved with a specified date within the last 90 days. You can download the extended version here.

11 thoughts on “Java Currency Conversion Class

  1. Hi,

    This has been really useful, thanks for making it.

    Just thought I’d let you know about a couple of problems I’ve come across while using it.

    Firstly, for me the cache was placed in file called tmpExchangeRates.xml rather than a file tmp/ExchangeRates.xml. To fix this, I used this code in the initCacheFile method:
    String tempdir = System.getProperty(“java.io.tmpdir”);
    if ( !(tempdir.endsWith(“/”) || tempdir.endsWith(“\\”)) )
    tempdir = tempdir + System.getProperty(“file.separator”);
    cacheFileName = tempdir + “ExchangeRates.xml”;

    The other problem I have just had was very amusing. I’m using the CurrencyConverter class to convert a whole table of currencies, but for some reason it is taking a few seconds to do this. I realised it must be downloading the cache file on every conversion. cacheIsExpired() is returning true every time, and the reason is: today is a bank holiday (Easter Monday), so the exchange rates haven’t been updated!

    I can’t think of an easy way to fix this. Could perhaps download a list of EU bank holidays for the coming year, and work it out from that.

    Anyway, thanks again, it’s been a very useful class.

  2. is it support CFA currency???
    i have tested but not working…

    its really good but not suits to my needs.

  3. You can find out which currencies are supported by typing this URL into your browser’s address field: http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml. I believe CFA (Franc?) is not one of them. The problem with bank holidays is indeed not addressed in this implementation. One could change/overwrite the cacheIsExpiredMethod() method to remember the last time the expiration time was checked and increase the tolerance value adaptively if the newly donwloaded XML file carries the old date. This would minimise attempts to re-download the file, but it adds a bit of complexity to the class.

  4. Is it possible to retrieve an XML from xe.com .. They seem to have far more exchange rates, would this work ? I just cant find the XML for xe.. Unless its private..

  5. sorry my mistake, i’ve already found how. this converter is really well done. it’s great to learn. thanks

  6. hi,
    i am trying to do smth like this:

    CurrencyConverter c = getInstance();

    System.out.println(c.convert(29.95, “SGD”,”USD”));

    Exception in thread “main” java.text.ParseException: Parser error: Content is not allowed in prolog.

    i am always getting this error,is there like something i should do,like store the XML file somewhere??

    Any help would be greatly appreciated

  7. The error message suggests that there is a non-validating XML file in the cache. Try clearing the cache and then restart.

    Cheers, Thomas

  8. Here is the fix for the code I found that did not work under Linux.

    private void initCacheFile()
    {
    if (cacheFile == null)
    {
    if (cacheFileName == null || cacheFileName.equals(“”))
    { /* Old Code that broke under Linux tried to write ExchangeRates.xml to
    * /tmpExchangeRates.xml, / is root and app has no permissions to write to root
    * filename should be /tmp/ExchangeRates.xml under linux. Note the extra /.
    *
    * cacheFileName = System.getProperty(“java.io.tmpdir”)
    * + “ExchangeRates.xml”;
    */

    /*
    * New code for fix.
    */
    cacheFile = new File(System.getProperty(“java.io.tmpdir”),”ExchangeRates.xml”);

    }
    }
    cacheFileName = cacheFile.getName();
    }

    I also added some extra methods which I have not posted that allow me to get an array of the Exchange Rate values or a single Exchange Rate.

    Thanks for the API, it has worked out for me and my project is almost complete.

    jrtroberts