根据连续的日期集合,获取并截取连续的日期区间.
业务场景:每一条记录对应一条交易记录,拿到每一条客户的交易日期,拼接成交易区间如:201801-201803,201805-201808这样的格式,中间的逗号是因为4月份该客户没有交易记录.
刚开始看到需求时,感觉代码处理起来应该不算复杂,但是等写起来的时候才发现逻辑上的处理还是蛮麻烦的,不好去判断是否有断月的情况,即便判断了还是要做复杂的月份拼接的ifelse操作去处理逻辑.最后和同事探讨了之后,复用了他之前写的一个方法,简单修改了一下就完成了这个场景代码的编写.
- handleInterval() 处理流水区间的主方法.sql排序拿到最早时间和最晚时间,调 2.getBetweenDate(开始时间,截止时间),得到最早月和最晚月之间的所有月份,遍历判断拼接就完事了
/**
* 处理流水区间
* @param entity
* @param applCode
*/
private void handleInterval(BankBillMarkDto entity, String applCode) {
List<String> timeInterval = new ArrayList<>();
if (PRI_BUSITYPE.equals(entity.getBusiType())) {
timeInterval = bankBillPrivateDAO.getTimeInterval(entity.getBankCardNo(), applCode);
} else if (PUB_BUSITYPE.equals(entity.getBusiType())) {
timeInterval = bankBillPublicDAO.getTimeInterval(entity.getBankCardNo(), applCode);
} //遍历拿到开始时间和截止时间
if (CollectionUtil.isNotEmpty(timeInterval)) {
String startTime = timeInterval.get(0).replace("-", "");
String endTime = timeInterval.get(timeInterval.size() - 1).replace("-", "");
List<String> period = getBetweenDate(startTime, endTime);
StringBuffer buffer = new StringBuffer();
buffer.append(startTime);
boolean isBroken = false;
//循环从开始到结束的每个年月
for (String month : period) {
// 有没有这个月
boolean hasMonth = false;
//遍历取到的每个月
for (String everyTrade : timeInterval) {
String tradeTime = everyTrade.replace("-", "");
//判断取到的月份是否缺某个月
if (month.substring(0, 6).equals(tradeTime)) {
//如果包含这个月
hasMonth = true;
if (isBroken) {
buffer.append(tradeTime);
isBroken = false;
}
//如果包含这个月, 跳出循环取到的月份
break;
}
}
if (!hasMonth && !isBroken) {
//拼接上个月
buffer.append("-" + getLastMonthDay(month).replace("-", "").substring(0, 6) + ",");
isBroken = true;
}
}
String s = buffer.toString();
if (s.endsWith(",")) {
s = s.substring(0, s.length() - 1);
} else {
s = s + "-" + endTime;
}
entity.setTimeInterval(s);
}
}
- getBetweenDate() 获取两个日期字符串之间的日期集合,传入开始月和结束月,返回开始月和结束月之间的所有月份(考虑月份跨年的情况)
/**
* 获取两个日期字符串之间的日期集合
* @param startTime:String
* @param endTime:String
* @return list:yyyyMM
*/
public static List<String> getBetweenDate(String startTime, String endTime) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
// 声明保存日期集合
List<String> list = new ArrayList<String>();
try {
// 转化成日期类型
Date startDate = sdf.parse(startTime);
Date endDate = sdf.parse(endTime);
//用Calendar 进行日期比较判断
Calendar calendar = Calendar.getInstance();
while (startDate.getTime() <= endDate.getTime()) {
// 把日期添加到集合
list.add(sdf.format(startDate));
// 设置日期
calendar.setTime(startDate);
//把日期增加一个月
calendar.add(Calendar.MONTH, 1);
// 获取增加后的日期
startDate = calendar.getTime();
}
} catch (ParseException e) {
log.error(" getBetweenDate :{} ", getExceptionMessage(e));
}
return list;
}
获取最近12个月的日期的交易记录,如果没有补0处理.
业务场景:获取最近12个月某个客户的交易金额总和,如果某个月没有记录,则返回0
- handlerMonth() 处理最近12个月的日期的交易记录.sql查出的是有交易记录的月份和总额,这个方法就是处理没有的月份,金额补0.先调用 2.getLatest12Month()拿到系统时间最近的12个月份(包含本月),调用上个业务场景的getBetweenDate(开始月份,结束月份) 再拿到sql的开始月份和结束月份,遍历判断是否存在系统时间的月份,如果不存在则补齐该月份
private void handlerMonth(List<TotalAmountTaxDTO> totalAmountTaxList) {
List<String> latest12Month = getLatest12Month();
List<String> mouths = new ArrayList<>();
for (TotalAmountTaxDTO totalAmountTaxDTO : totalAmountTaxList) {
mouths.add(totalAmountTaxDTO.getInvoiceDate());
}
String startTime = latest12Month.get(0);
String endTime = latest12Month.get(latest12Month.size() - 1);
List<String> period = getBetweenDate(startTime, endTime);
//循环从开始到结束的每个年月
for (int i = 0; i < period.size(); i++) {
//遍历取到的每个月
//如果不包含这个月
if (!mouths.contains(period.get(i))) {
totalAmountTaxList.add(i, new TotalAmountTaxDTO(period.get(i), "0"));
}
}
}
- getLatest12Month() 获取当前系统时间最近12月的年月(含当月)以及格式化月份(<10的月份前面补0)
public static List<String> getLatest12Month() {
String[] latest12Months = new String[12];
Calendar cal = Calendar.getInstance();
//把当前的系统日期设置为当月1号,防止月份天数不一样的情况
cal.set(Calendar.DAY_OF_MONTH, 1);
for (int i = 0; i < 12; i++) {
latest12Months[11 - i] = cal.get(Calendar.YEAR) + fillZero(cal.get(Calendar.MONTH) + 1);
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1); //逐次往前推1个月
}
return Arrays.asList(latest12Months);
}
/**
* 格式化月份
*/
public static String fillZero(int i) {
String month = "";
if (i < 10) {
month = "0" + i;
} else {
month = String.valueOf(i);
}
return month;
}