4

I'm trying to get exchange rate on specific date between EUR and USD. The issue is I'm allways getting exchange dare for date: LocalDate{year=2016, month=1, dayOfMonth=8} and it does not matter if I specify date in query.

Here are my maven dependencies:

        <dependency>
            <groupId>javax.money</groupId>
            <artifactId>money-api-bp</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.javamoney</groupId>
            <artifactId>moneta-bp</artifactId>
            <version>1.1</version>
        </dependency>

Source code:

public class Test {
    public static void main(String[] args) {
        ConversionQuery query = ConversionQueryBuilder.of()
                .setProviderName("ECB")
                .setBaseCurrency(Monetary.getCurrency("EUR"))
                .setTermCurrency(Monetary.getCurrency("USD"))
                .set(LocalDate.class, LocalDate.of(2017, Month.SEPTEMBER, 10))
                .build();
        final ExchangeRateProvider provider = getExchangeRateProvider(query);
        final ExchangeRate rate1 = provider.getExchangeRate(query);
        System.out.println(rate1);

        ExchangeRateProvider ecbExchangeRateProvider = MonetaryConversions.getExchangeRateProvider("ECB");
        ExchangeRate rate = ecbExchangeRateProvider.getExchangeRate("EUR", "USD");
        System.out.println(rate);

    }
}

And the output from sout:

sep. 11, 2017 9:58:29 AM org.javamoney.moneta.internal.convert.ECBAbstractRateProvider newDataLoaded
INFO: Loaded ECBCurrentRateProvider exchange rates for days:1
sep. 11, 2017 9:58:30 AM org.javamoney.moneta.internal.convert.ECBAbstractRateProvider newDataLoaded
INFO: Loaded ECBHistoric90RateProvider exchange rates for days:63
ExchangeRate [base=EUR, factor=1.0861, conversionContext=ConversionContext (
{provider=ECB, rateTypes=[DEFERRED], providerDescription=European Central Bank, days=1, org.javamoney.moneta.internal.convert.LocalDate=LocalDate{year=2016, month=1, dayOfMonth=8}, javax.money.convert.RateType=HISTORIC})]
ExchangeRate [base=EUR, factor=1.0861, conversionContext=ConversionContext (
{provider=ECB, rateTypes=[DEFERRED], providerDescription=European Central Bank, days=1, org.javamoney.moneta.internal.convert.LocalDate=LocalDate{year=2016, month=1, dayOfMonth=8}, javax.money.convert.RateType=HISTORIC})]
ExchangeRate [base=USD, factor=0.9207255317189946, conversionContext=ConversionContext (
{provider=ECB, rateTypes=[DEFERRED], providerDescription=European Central Bank, days=1, org.javamoney.moneta.internal.convert.LocalDate=LocalDate{year=2016, month=1, dayOfMonth=8}, javax.money.convert.RateType=HISTORIC})]
sep. 11, 2017 9:58:35 AM org.javamoney.moneta.internal.convert.ECBAbstractRateProvider newDataLoaded
INFO: Loaded ECBHistoricRateProvider exchange rates for days:4358

Thanks!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Kiki
  • 2,243
  • 5
  • 30
  • 43
  • Which `LocalDate` class are you importing? – Andy Turner Sep 11 '17 at 08:10
  • The `LocaleDate` seems like the one from JDK8. Why are you using the backport library (`-bp`) which is explicitly compiled with JDK7? – vl4d1m1r4 Sep 11 '17 at 08:41
  • I'm using java.time.LocalDate as an import. Because if i'm using dependency on money-api without bp I get null as an result. And wrong import does not explain why I get some old day in second example. And if i change to: .set(org.javamoney.moneta.internal.convert.LocalDate.class, org.javamoney.moneta.internal.convert.LocalDate.from(Calendar.getInstance())) i get the same issue. – Kiki Sep 11 '17 at 09:47

1 Answers1

3

This API is currently obscure. If you get:

ConversionQueryBuilder.of().setTermCurrency("EUR").
        set(LocalDate.class, LocalDate.of(2018, 1, 1)).build()
MonetaryConversions.getConversion(conversionQuery)

It will use following method:

default CurrencyConversion getConversion(ConversionQuery conversionQuery) {
    return getExchangeRateProvider(conversionQuery).getCurrencyConversion(
            Objects.requireNonNull(conversionQuery.getCurrency(), "Terminating Currency is required.")
    );
}

As you can see, the conversionQuery is used to get the provider, not the conversion object itself. It's always returned for query with only currency set, never with date.

To make it working use:

MonetaryConversions.getExchangeRateProvider().getCurrencyConversion(conversionQuery)

I believe it should work consistently for all invocations.

Lukasz Frankowski
  • 2,955
  • 1
  • 31
  • 32