Skip to content

ethauvin/frankfurter4j

Repository files navigation

Frankfurter for Java: Retrieve Reference Exchange Rates

License (3-Clause BSD) Java bld release Maven Central Maven metadata URL

Known Vulnerabilities Quality Gate Status GitHub CI CircleCI

Retrieve reference exchange rates from Frankfurter.dev, a free, open-source currency data API.

Examples (TL;DR)

var latestRates = new LatestRates.Builder()
        .amount(100.0)
        .base("USD")
        .symbols("EUR", "GBP")
        .build();
var exchangeRates = latestRates.exchangeRates();
var euro = exchangeRates.rateFor("EUR");
var britishPound = exchangeRates.rateFor("GBP");

To get the latest exchange rates for the United States Dollar in Euro and British Pound.

bld

To use with bld, include the following dependency in your build file:

repositories = List.of(MAVEN_CENTRAL, CENTRAL_SNAPSHOTS);

scope(compile)
    .include(dependency("net.thauvin.erik:frankfurter4j:0.9.1"));

Gradle, Maven, etc

To use with Gradle, include the following dependency in your build file:

repositories {
    maven {
        name = 'Central Portal Snapshots'
        url = 'https://central.sonatype.com/repository/maven-snapshots/'
    }
    mavenCentral()
}

dependencies {
    implementation("net.thauvin.erik:frankfurter4j:0.9.1")
}

Instructions for using with Maven, Ivy, etc. can be found on Maven Central.

Latest Rates

To fetch the latest working day's rates:

var latestRates = new LatestRates.Builder().build();
var exchangeRates = latestRates.exchangeRates();

The latest exchange rates will be stored in the ExchangeRates class:

if (exchangeRates.hasRateFor("JPY")) {
    var jpy = exchangeRates.rateFor("JPY");
}

To change the base currency use the builder's base method. The default is EUR.

var latestRates = new LatestRates.Builder()
        .base("USD")
        .build();

To limit the response to specific target currencies.

var latestRates = new LatestRates.Builder()
        .symbols("CHF", "GBP")
        .build();

Historical Rates

To retrieve rates for a specific date.

var latestRates = new LatestRates.Builder()
        .date(LocalDate.of(1999, 1, 4))
        .build();

To change the base currency and filter target currencies.

var latestRates = new LatestRates.Builder()
        .base("USD")
        .date(LocalDate.of(1999, 1, 4))
        .symbols("EUR")
        .build();

Note: As mentioned on the website, Frankfurter stores dates in UTC. If you use a different time zone, be aware that you may be querying with a different calendar date than intended. Also, data returned for today is not stable and will update if new rates are published.

Time Series Data

To fetch rates over a period.

var timeSeries = new TimeSeries.Builder()
        .startDate(LocalDate.of(2000, 1, 1))
        .endDate(LocalDate.of(2000, 12, 31))
        .build();
var periodicRates = timeSeries.periodicRates();

The periodic rates will be stored in the TimeSeries class.

var firstMarketDay = LocalDate.of(2000, 1, 4);
if (periodicRates.hasRatesFor(firstMarketDay)) {
    // Get the Yen rate directly
    var yen = periodicRates.rateFor(firstMarketDay, "JPY");

    // Get the Dollar rate if available
    var rates = periodicRates.rateFor(firstMarketDay);
    if (rates.containsKey("USD")) {
        var usd = rates.get("USD");
    }
}

// Loop through all dates
periodicRates.dates().forEach(date -> {
    // Print the date
    System.out.println("Rates for " + date);
    // Loop through all rates
    periodicRates.ratesFor(date).forEach((symbol, rate) -> {
        // Print the symbol and rate, e.g., USD: 0.9059
        System.out.println("    " + symbol + ": " + rate); 
    });
});

To fetch rates up to the present.

var timeSeries = new TimeSeries.Builder()
        .startDate(LocalDate.of(2025, 1, 1))
        .build();

To filter currencies to reduce response size and improve performance.

var timeSeries = new TimeSeries.Builder()
        .startDate(LocalDate.of(2025, 1, 1))
        .endDate(LocalDate.now())
        .symbols("USD")
        .build();

Available currencies

The currencies are stored in a CurrencyRegistry which contains Currency records.

var currencies = CurrencyRegistry.getInstance();
var usd = currencies.findBySymbol("USD"); // case-insensitive
if (usd.isPresent()) {
    var name = usd.get().name(); // United States Dollar
    var symbol = usd.get().symbol(); // USD
    var locale = usd.get().locale(); // Locale.US
}

currencies.findBySymbol("usd"); // case-insensitive
currencies.findBySymbol("EUR"); // the record for Euro

currencies.findByName("euro"); // the record for EUR
currencies.findByName(".*Japan.*"); // the record for JPY

currencies.search(".*Dollar$"); //  list of matching currencies

currencies.contains("JPY"); // true

The currently supported currencies are:

Symbol Name
AUD Australian Dollar
BGN Bulgarian Lev
BRL Brazilian Real
CAD Canadian Dollar
CHF Swiss Franc
CNY Chinese Renminbi Yuan
CZK Czech Koruna
DKK Danish Krone
EUR Euro
GBP British Pound
HKD Hong Kong Dollar
HUF Hungarian Forint
IDR Indonesian Rupiah
ILS Israeli New Sheqel
INR Indian Rupee
ISK Icelandic Króna
JPY Japanese Yen
KRW South Korean Won
MXN Mexican Peso
MYR Malaysian Ringgit
NOK Norwegian Krone
NZD New Zealand Dollar
PHP Philippine Peso
PLN Polish Złoty
RON Romanian Leu
SEK Swedish Krona
SGD Singapore Dollar
THB Thai Baht
TRY Turkish Lira
USD United States Dollar
ZAR South African Rand

This list is maintained internally as it is unlikely to change. Although, to fully implement the API, the list could be refreshed using:

currencies.refresh();

Currency Conversion

You can perform currency conversion by fetching the exchange rate with a specified amount.

var latestRates = new LatestRates.Builder()
        .amount(10)
        .base("USD")
        .symbols("EUR")
        .build();
var exchangeRates = latestRates.exchangeRates();
var euro = exchangeRates.rateFor("EUR");

System.out.println("$10 = €" + euro); // $10 = €8.8059

Working Days

You can retrieve a list of working days (non-weekends, non-closing days) between two dates.

var workingDays = FrankfurterUtils.workingDays(
        LocalDate.of(2021, 1, 1), LocalDate.of(2021, 1, 31));

var firstWorkingDay = workingDays.get(0); // 2021-01-04
var lastWorkingDay = workingDays.get(workingDays.size() - 1); // 2025-01-29

Currency Format

You can also format amounts for specific currencies.

CurrencyFormatter.formatCurrency("USD", 100.0); // $100.00
CurrencyFormatter.fomartCurrency("EUR", 1234.567); // 1.234,567 €
CurrencyFormatter.fomartCurrency("EUR", 1234.567, true); // 1.234,57 € rounded

Contributing

See CONTIBUTING.md for information about contributing to this project.

More…

If all else fails, there's always more Documentation.