背景描述:在金融业务中经常涉及到交易日期的计算交易日和自然日是有区别的比如法定节假日周末都是不能交易的我们叫非交易日允许交易的日我们称之为交易日。交易日每天也不是24小时比如中国股市的股票交易时间在每个交易日的AM930-1130 和 PM1300-1500。为了满足724小时服务我们对用户提供的服务在非交易日或是非交易时段也是有支持的所以将非交易时段产生的业务它的交易日会算到下一个最近交易时段的
// 可以使用Java8的LocalDateTime和LocalDate来处理日期时间 import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.List;
public class TradeDayTool {
private List<LocalDate> tradeDayList;
public void init(List<String> tradeDayList) {
this.tradeDayList = tradeDayList.stream()
.map(dateStr -> LocalDate.parse(dateStr, DateTimeFormatter.BASIC_ISO_DATE))
.sorted()
.toList();
}
public String getTradeDay(LocalDateTime time, int offsetDays) {
// 先将时间转换为LocalDate,并找到该日期在交易日历中的索引位置
LocalDate date = time.toLocalDate();
int index = findTradeDayIndex(date);
// 如果指定偏移量为0,则直接返回当前交易日
if (offsetDays == 0) {
return tradeDayList.get(index).format(DateTimeFormatter.BASIC_ISO_DATE);
}
// 根据偏移量计算目标交易日的索引位置
int targetIndex = index + offsetDays / Math.abs(offsetDays);
if (targetIndex < 0) {
targetIndex = 0;
} else if (targetIndex >= tradeDayList.size()) {
targetIndex = tradeDayList.size() - 1;
}
// 如果目标交易日的索引位置与当前交易日相同,则直接返回当前交易日
if (targetIndex == index) {
return tradeDayList.get(index).format(DateTimeFormatter.BASIC_ISO_DATE);
}
// 根据目标交易日的索引位置计算目标日期,并调整时间部分
LocalDate targetDate = tradeDayList.get(targetIndex);
LocalTime targetTime = time.toLocalTime();
if (targetIndex > index) {
targetTime = LocalTime.MIN;
} else {
targetTime = LocalTime.MAX;
}
// 将目标日期和时间合并为LocalDateTime,并返回格式化后的字符串
LocalDateTime targetDateTime = LocalDateTime.of(targetDate, targetTime);
return targetDateTime.format(DateTimeFormatter.BASIC_ISO_DATE);
}
// 找到给定日期在交易日历中的索引位置
private int findTradeDayIndex(LocalDate date) {
int index = 0;
for (LocalDate tradeDay : tradeDayList) {
if (date.isBefore(tradeDay)) {
break;
}
index++;
}
return index - 1;
}
// 测试用例
public static void main(String[] args) {
TradeDayTool tool = new TradeDayTool();
tool.init(List.of("20160701", "20160704", "20160705"));
LocalDateTime time1 = LocalDateTime.of(2016, 7, 1, 8, 0);
LocalDateTime time2 = LocalDateTime.of(2016, 7, 1, 17, 0);
LocalDateTime time3 = LocalDateTime.of(2016, 7, 2, 12, 0);
LocalDateTime time4 = LocalDateTime.of(2016, 7, 3, 12, 0);
LocalDateTime time5 = LocalDateTime.of(2016, 7, 4, 9, 0);
LocalDateTime time6 = LocalDateTime.of(2016, 7, 4, 18, 0);
LocalDateTime time7 = LocalDateTime.of(2016, 7, 5, 12, 0);
assert tool.getTradeDay(time1, 0).equals("20160701");
assert tool.getTradeDay(time1, 1).equals("20160704");
assert tool.getTradeDay(time2, 0).equals("20160704");
assert tool.getTradeDay(time2, 1).equals("20160705");
assert tool.getTradeDay(time3, 1).equals("20160705");
assert tool.getTradeDay(time4, 1).equals("20160705");
assert tool.getTradeDay(time5, -1).equals("20160630");
assert tool.getTradeDay(time6, 0).equals("20160705");
assert tool.getTradeDay(time7, 0).equals("20160705");
}
原文地址: https://www.cveoy.top/t/topic/fftc 著作权归作者所有。请勿转载和采集!