Skip to content

Commit ce0fbbd

Browse files
committed
JAVAMONEY-89: Removed timestamp methods.
1 parent f6e9ab5 commit ce0fbbd

File tree

9 files changed

+71
-81
lines changed

9 files changed

+71
-81
lines changed

src/main/java/org/javamoney/moneta/convert/internal/AbstractECBCurrentRateProvider.java

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
import java.math.MathContext;
2020
import java.net.MalformedURLException;
2121
import java.time.LocalDate;
22-
import java.time.ZoneId;
23-
import java.util.Comparator;
24-
import java.util.Date;
22+
import java.time.LocalDateTime;
2523
import java.util.Map;
2624
import java.util.Objects;
2725
import java.util.concurrent.ConcurrentHashMap;
@@ -63,14 +61,12 @@ abstract class AbstractECBCurrentRateProvider extends AbstractRateProvider imple
6361
/**
6462
* Historic exchange rates, rate timestamp as UTC long.
6563
*/
66-
private final Map<Long, Map<String, ExchangeRate>> historicRates = new ConcurrentHashMap<>();
64+
private final Map<LocalDate, Map<String, ExchangeRate>> historicRates = new ConcurrentHashMap<>();
6765
/**
6866
* Parser factory.
6967
*/
7068
private SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
7169

72-
private Long recentKey;
73-
7470
public AbstractECBCurrentRateProvider(ProviderContext context) throws MalformedURLException {
7571
super(context);
7672
saxParserFactory.setNamespaceAware(false);
@@ -88,7 +84,6 @@ public void newDataLoaded(String data, InputStream is) {
8884
try {
8985
SAXParser parser = saxParserFactory.newSAXParser();
9086
parser.parse(is, new RateReadingHandler(historicRates, getProviderContext()));
91-
recentKey = null;
9287
} catch (Exception e) {
9388
LOGGER.log(Level.FINEST, "Error during data load.", e);
9489
}
@@ -103,13 +98,19 @@ public ExchangeRate getExchangeRate(ConversionQuery query) {
10398
if (historicRates.isEmpty()) {
10499
return null;
105100
}
106-
107-
Long timeStampMillis = getMillisSeconds(query);
108-
ExchangeRateBuilder builder = getBuilder(query, timeStampMillis);
109-
101+
LocalDate date = query.get(LocalDate.class);
102+
if (date == null) {
103+
LocalDateTime dateTime = query.get(LocalDateTime.class);
104+
if (dateTime != null) {
105+
date = dateTime.toLocalDate();
106+
} else {
107+
date = LocalDate.now();
108+
}
109+
}
110+
ExchangeRateBuilder builder = getBuilder(query, date);
110111

111112
Map<String, ExchangeRate> targets = this.historicRates
112-
.get(timeStampMillis);
113+
.get(date);
113114
if (Objects.isNull(targets)) {
114115
return null;
115116
}
@@ -157,32 +158,11 @@ private boolean areBothBaseCurrencies(ConversionQuery query) {
157158
BASE_CURRENCY_CODE.equals(query.getCurrency().getCurrencyCode());
158159
}
159160

160-
private Long getMillisSeconds(ConversionQuery query) {
161-
if (Objects.nonNull(query.getTimestamp())) {
162-
LocalDate timeStamp = query.getTimestamp().toLocalDate();
163-
164-
Date date = Date.from(timeStamp.atStartOfDay()
165-
.atZone(ZoneId.systemDefault()).toInstant());
166-
Long timeStampMillis = date.getTime();
167-
return timeStampMillis;
168-
} else {
169-
return getRecentKey();
170-
}
171-
}
172-
173-
private Long getRecentKey() {
174-
if (Objects.isNull(recentKey)) {
175-
Comparator<Long> reversed = Comparator.<Long>naturalOrder().reversed();
176-
recentKey = historicRates.keySet().stream().sorted(reversed).findFirst().get();
177-
}
178-
return recentKey;
179-
}
180161

181-
private ExchangeRateBuilder getBuilder(ConversionQuery query,
182-
Long timeStampMillis) {
162+
private ExchangeRateBuilder getBuilder(ConversionQuery query, LocalDate localDate) {
183163
ExchangeRateBuilder builder = new ExchangeRateBuilder(
184164
ConversionContextBuilder.create(getProviderContext(), RateType.HISTORIC)
185-
.setTimestampMillis(timeStampMillis).build());
165+
.set(localDate).build());
186166
builder.setBase(query.getBaseCurrency());
187167
builder.setTerm(query.getCurrency());
188168
return builder;

src/main/java/org/javamoney/moneta/convert/internal/IMFRateProvider.java

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import java.text.DecimalFormat;
2424
import java.text.NumberFormat;
2525
import java.text.ParseException;
26-
import java.text.SimpleDateFormat;
26+
import java.time.LocalDate;
27+
import java.time.LocalDateTime;
28+
import java.time.format.DateTimeFormatter;
2729
import java.util.ArrayList;
2830
import java.util.Collections;
2931
import java.util.Currency;
@@ -151,7 +153,7 @@ private void loadRatesTSV(InputStream inputStream) throws IOException, ParseExce
151153
// Currency January 31, 2013 January 30, 2013 January 29, 2013
152154
// January 28, 2013 January 25, 2013
153155
// Euro 1.137520 1.137760 1.143840 1.142570 1.140510
154-
List<Long> timestamps = null;
156+
List<LocalDate> timestamps = null;
155157
while (Objects.nonNull(line)) {
156158
if (line.trim().isEmpty()) {
157159
line = pr.readLine();
@@ -182,24 +184,23 @@ private void loadRatesTSV(InputStream inputStream) throws IOException, ParseExce
182184
if (Objects.isNull(values[i])) {
183185
continue;
184186
}
185-
Long fromTS = timestamps != null ? timestamps.get(i) : null;
187+
LocalDate fromTS = timestamps != null ? timestamps.get(i) : null;
186188
if (fromTS == null) {
187189
continue;
188190
}
189-
Long toTS = fromTS + 3600L * 1000L * 24L; // One day
190191
RateType rateType = RateType.HISTORIC;
191-
if (toTS > System.currentTimeMillis()) {
192+
if (fromTS.equals(LocalDate.now())) {
192193
rateType = RateType.DEFERRED;
193194
}
194195
if (currencyToSdr) { // Currency -> SDR
195196
ExchangeRate rate = new ExchangeRateBuilder(
196-
ConversionContextBuilder.create(CONTEXT, rateType).setTimestampMillis(toTS).build())
197+
ConversionContextBuilder.create(CONTEXT, rateType).set(fromTS).build())
197198
.setBase(currency).setTerm(SDR).setFactor(new DefaultNumberValue(1d / values[i])).build();
198199
List<ExchangeRate> rates = newCurrencyToSdr.computeIfAbsent(currency, c -> new ArrayList<>(5));
199200
rates.add(rate);
200201
} else { // SDR -> Currency
201202
ExchangeRate rate = new ExchangeRateBuilder(
202-
ConversionContextBuilder.create(CONTEXT, rateType).setTimestampMillis(fromTS).build())
203+
ConversionContextBuilder.create(CONTEXT, rateType).set(fromTS).build())
203204
.setBase(SDR).setTerm(currency).setFactor(DefaultNumberValue.of(1d / values[i])).build();
204205
List<ExchangeRate> rates = newSdrToCurrency.computeIfAbsent(currency, (c) -> new ArrayList<>(5));
205206
rates.add(rate);
@@ -227,14 +228,14 @@ private Double[] parseValues(NumberFormat f, String[] parts) throws ParseExcepti
227228
return result;
228229
}
229230

230-
private List<Long> readTimestamps(String line) throws ParseException {
231+
private List<LocalDate> readTimestamps(String line) throws ParseException {
231232
// Currency May 01, 2013 April 30, 2013 April 29, 2013 April 26, 2013
232233
// April 25, 2013
233-
SimpleDateFormat sdf = new SimpleDateFormat("MMM DD, yyyy", Locale.ENGLISH);
234+
DateTimeFormatter sdf = DateTimeFormatter.ofPattern("MMMM dd, uuuu").withLocale(Locale.ENGLISH);
234235
String[] parts = line.split("\\\t");
235-
List<Long> dates = new ArrayList<>(parts.length);
236+
List<LocalDate> dates = new ArrayList<>(parts.length);
236237
for (int i = 1; i < parts.length; i++) {
237-
dates.add(sdf.parse(parts[i]).getTime());
238+
dates.add(LocalDate.parse(parts[i], sdf));
238239
}
239240
return dates;
240241
}
@@ -246,7 +247,13 @@ public ExchangeRate getExchangeRate(ConversionQuery conversionQuery) {
246247
}
247248
CurrencyUnit base = conversionQuery.getBaseCurrency();
248249
CurrencyUnit term = conversionQuery.getCurrency();
249-
Long timestamp = conversionQuery.getTimestampMillis();
250+
LocalDate timestamp = conversionQuery.get(LocalDate.class);
251+
if (timestamp == null) {
252+
LocalDateTime dateTime = conversionQuery.get(LocalDateTime.class);
253+
if (dateTime != null) {
254+
timestamp = dateTime.toLocalDate();
255+
}
256+
}
250257
ExchangeRate rate1 = lookupRate(currencyToSdr.get(base), timestamp);
251258
ExchangeRate rate2 = lookupRate(sdrToCurrency.get(term), timestamp);
252259
if (base.equals(SDR)) {
@@ -266,16 +273,16 @@ public ExchangeRate getExchangeRate(ConversionQuery conversionQuery) {
266273
return builder.build();
267274
}
268275

269-
private ExchangeRate lookupRate(List<ExchangeRate> list, Long timestamp) {
276+
private ExchangeRate lookupRate(List<ExchangeRate> list, LocalDate localDate) {
270277
if (Objects.isNull(list)) {
271278
return null;
272279
}
273280
ExchangeRate found = null;
274281
for (ExchangeRate rate : list) {
275-
if (Objects.isNull(timestamp)) {
276-
timestamp = System.currentTimeMillis();
282+
if (Objects.isNull(localDate)) {
283+
localDate = LocalDate.now();
277284
}
278-
if (isValid(rate.getConversionContext(), timestamp)) {
285+
if (isValid(rate.getConversionContext(), localDate)) {
279286
return rate;
280287
}
281288
if (Objects.isNull(found)) {
@@ -285,11 +292,9 @@ private ExchangeRate lookupRate(List<ExchangeRate> list, Long timestamp) {
285292
return found;
286293
}
287294

288-
private boolean isValid(ConversionContext conversionContext, Long timestamp) {
289-
Long validFrom = conversionContext.getLong("validFrom");
290-
Long validTo = conversionContext.getLong("validTo");
291-
return !(Objects.nonNull(validFrom) && validFrom > timestamp) &&
292-
!(Objects.nonNull(validTo) && validTo < timestamp);
295+
private boolean isValid(ConversionContext conversionContext, LocalDate timestamp) {
296+
LocalDate validAt = conversionContext.get(LocalDate.class);
297+
return !(Objects.nonNull(validAt)) && validAt.equals(timestamp);
293298
}
294299

295300
}

src/main/java/org/javamoney/moneta/convert/internal/RateReadingHandler.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import java.math.BigDecimal;
44
import java.time.LocalDate;
5-
import java.time.ZoneId;
6-
import java.util.Date;
75
import java.util.Map;
86
import java.util.Objects;
97
import java.util.Optional;
@@ -44,13 +42,13 @@ class RateReadingHandler extends DefaultHandler {
4442
/**
4543
* Current timestamp for the given section.
4644
*/
47-
private long timestamp;
45+
private LocalDate localDate;
4846

49-
private final Map<Long, Map<String, ExchangeRate>> historicRates;
47+
private final Map<LocalDate, Map<String, ExchangeRate>> historicRates;
5048

5149
private ProviderContext context;
5250

53-
public RateReadingHandler(Map<Long, Map<String, ExchangeRate>> historicRates, ProviderContext context) {
51+
public RateReadingHandler(Map<LocalDate, Map<String, ExchangeRate>> historicRates, ProviderContext context) {
5452
this.historicRates = historicRates;
5553
this.context = context;
5654
}
@@ -61,14 +59,12 @@ public void startElement(String uri, String localName, String qName,
6159
if ("Cube".equals(qName)) {
6260
if (Objects.nonNull(attributes.getValue("time"))) {
6361

64-
Date date = Date.from(LocalDate.parse(attributes.getValue("time")).atStartOfDay()
65-
.atZone(ZoneId.systemDefault()).toInstant());
66-
timestamp = date.getTime();
62+
this.localDate = LocalDate.parse(attributes.getValue("time")).atStartOfDay().toLocalDate();
6763
} else if (Objects.nonNull(attributes.getValue("currency"))) {
6864
// read data <Cube currency="USD" rate="1.3349"/>
6965
CurrencyUnit tgtCurrency = MonetaryCurrencies
7066
.getCurrency(attributes.getValue("currency"));
71-
addRate(tgtCurrency, timestamp, BigDecimal.valueOf(Double
67+
addRate(tgtCurrency, this.localDate, BigDecimal.valueOf(Double
7268
.parseDouble(attributes.getValue("rate"))));
7369
}
7470
}
@@ -82,27 +78,28 @@ public void startElement(String uri, String localName, String qName,
8278
* @param timestamp The target day.
8379
* @param rate The rate.
8480
*/
85-
void addRate(CurrencyUnit term, long timestamp, Number rate) {
81+
void addRate(CurrencyUnit term, LocalDate localDate, Number rate) {
8682
RateType rateType = RateType.HISTORIC;
8783
ExchangeRateBuilder builder;
88-
if (Objects.nonNull(timestamp)) {
89-
if (timestamp > System.currentTimeMillis()) {
84+
if (Objects.nonNull(localDate)) {
85+
// TODO check/test!
86+
if (localDate.equals(LocalDate.now())) {
9087
rateType = RateType.DEFERRED;
9188
}
9289
builder = new ExchangeRateBuilder(
93-
ConversionContextBuilder.create(context, rateType).setTimestampMillis(timestamp).build());
90+
ConversionContextBuilder.create(context, rateType).set(localDate).build());
9491
} else {
9592
builder = new ExchangeRateBuilder(ConversionContextBuilder.create(context, rateType).build());
9693
}
9794
builder.setBase(ECBHistoricRateProvider.BASE_CURRENCY);
9895
builder.setTerm(term);
9996
builder.setFactor(DefaultNumberValue.of(rate));
10097
ExchangeRate exchangeRate = builder.build();
101-
Map<String, ExchangeRate> rateMap = this.historicRates.get(timestamp);
98+
Map<String, ExchangeRate> rateMap = this.historicRates.get(localDate);
10299
if (Objects.isNull(rateMap)) {
103100
synchronized (this.historicRates) {
104-
rateMap = Optional.ofNullable(this.historicRates.get(timestamp)).orElse(new ConcurrentHashMap<>());
105-
this.historicRates.putIfAbsent(timestamp, rateMap);
101+
rateMap = Optional.ofNullable(this.historicRates.get(localDate)).orElse(new ConcurrentHashMap<>());
102+
this.historicRates.putIfAbsent(localDate, rateMap);
106103

107104
}
108105
}

src/main/java/org/javamoney/moneta/internal/ConfigurableCurrencyUnitProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import javax.money.CurrencyQuery;
1919
import javax.money.CurrencyUnit;
2020
import javax.money.spi.CurrencyProviderSpi;
21+
import java.time.LocalDate;
22+
import java.time.LocalDateTime;
2123
import java.util.*;
2224
import java.util.concurrent.ConcurrentHashMap;
2325

@@ -46,7 +48,7 @@ public class ConfigurableCurrencyUnitProvider implements CurrencyProviderSpi {
4648
*/
4749
public Set<CurrencyUnit> getCurrencies(CurrencyQuery currencyQuery) {
4850
Set<CurrencyUnit> result = new HashSet<>(currencyUnits.size());
49-
if (currencyQuery.getTimestamp() != null) {
51+
if (currencyQuery.get(LocalDateTime.class) != null || currencyQuery.get(LocalDate.class) != null) {
5052
return Collections.emptySet();
5153
}
5254
if (!currencyQuery.getCurrencyCodes().isEmpty()) {

src/main/java/org/javamoney/moneta/internal/DefaultRoundingProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import javax.money.spi.RoundingProviderSpi;
2020
import java.math.MathContext;
2121
import java.math.RoundingMode;
22+
import java.time.LocalDate;
23+
import java.time.LocalDateTime;
2224
import java.util.*;
2325

2426
/**
@@ -47,7 +49,7 @@ public String getProviderName() {
4749
* @return the (shared) default rounding instances matching, never null.
4850
*/
4951
public MonetaryRounding getRounding(RoundingQuery roundingQuery) {
50-
if (roundingQuery.getTimestamp() != null) {
52+
if (roundingQuery.get(LocalDateTime.class) != null || roundingQuery.get(LocalDate.class) != null) {
5153
return null;
5254
}
5355
CurrencyUnit currency = roundingQuery.getCurrency();

src/test/java/org/javamoney/moneta/convert/internal/ECBHistoric90RateProviderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public void shouldSetTimeInLocalDateTime() {
149149
.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
150150

151151
ConversionQuery conversionQuery = ConversionQueryBuilder.of()
152-
.setTermCurrency(EURO).setTimestamp(localDate).build();
152+
.setTermCurrency(EURO).set(localDate).build();
153153
CurrencyConversion currencyConversion = provider
154154
.getCurrencyConversion(conversionQuery);
155155
assertNotNull(currencyConversion);

src/test/java/org/javamoney/moneta/convert/internal/ECBHistoricRateProviderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public void shouldSetTimeInLocalDateTime() {
146146

147147
LocalDate localDate = YearMonth.of(2014, Month.JANUARY).atDay(9);
148148
ConversionQuery conversionQuery = ConversionQueryBuilder.of()
149-
.setTermCurrency(EURO).setTimestamp(localDate).build();
149+
.setTermCurrency(EURO).set(localDate).build();
150150
CurrencyConversion currencyConversion = provider
151151
.getCurrencyConversion(conversionQuery);
152152
assertNotNull(currencyConversion);

src/test/java/org/javamoney/moneta/function/MonetaryRoundingsTest.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import javax.money.*;
2121
import java.math.BigDecimal;
2222
import java.math.RoundingMode;
23+
import java.time.LocalDate;
24+
import java.time.LocalDateTime;
25+
import java.time.temporal.ChronoUnit;
2326
import java.util.Currency;
2427

2528
import static org.testng.Assert.*;
@@ -160,7 +163,7 @@ public void testGetCashRoundingCurrencyUnit() {
160163
public void testGetRoundingCurrencyUnitLong() {
161164
MonetaryOperator r = MonetaryRoundings.getRounding(
162165
RoundingQueryBuilder.of().setCurrency(MonetaryCurrencies.getCurrency("XXX"))
163-
.setTimestampMillis(System.currentTimeMillis() + 20000L).build());
166+
.set(LocalDate.now().plus(1, ChronoUnit.DAYS)).build());
164167
assertNotNull(r);
165168
assertEquals(MonetaryAmounts.getDefaultAmountFactory().setCurrency("XXX").setNumber(-1).create(),
166169
MonetaryAmounts.getDefaultAmountFactory().setCurrency("XXX").setNumber(2.0234343).create()
@@ -176,7 +179,7 @@ public void testGetRoundingCurrencyUnitLong() {
176179
public void testGetCashRoundingCurrencyUnitLong() {
177180
MonetaryOperator r = MonetaryRoundings.getRounding(
178181
RoundingQueryBuilder.of().setCurrency(MonetaryCurrencies.getCurrency("XXX"))
179-
.setTimestampMillis(System.currentTimeMillis() + 20000L).set("cashRounding", true).build());
182+
.set(LocalDate.now().plus(1, ChronoUnit.DAYS)).set("cashRounding", true).build());
180183
assertNotNull(r);
181184
assertEquals(MonetaryAmounts.getDefaultAmountFactory().setCurrency("CHF").setNumber(-1).create(),
182185
MonetaryAmounts.getDefaultAmountFactory().setCurrency("CHF").setNumber(2.0234343).create()

0 commit comments

Comments
 (0)