根據連續的日期集合,獲取並截取連續的日期區間.
業務場景:每一條記錄對應一條交易記錄,拿到每一條客戶的交易日期,拼接成交易區間如: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;
}