工作中遇到这种需求了,就写了一个方法,测试了几种情况都没有问题
代码中的工具类用的hutool,不能用第三方包的话,可以把工具类的api都换成自己写的计算方法
/**
* 处理单个时间段中的节假日
*
* @param m 时间段
* @return 处理过后的一个或多个时间段
*/
public static List<Map<String, Date>> dispose(Map<String, Date> m, List<String> holidays, List<String> workDays) {
String ymd = "yyyy-MM-dd";
Date st = DateUtil.beginOfDay(m.get("st")).toJdkDate();
Date et = DateUtil.beginOfDay(m.get("et")).toJdkDate();
if (st == null || et == null) {
return new ArrayList<>();
}
List<Map<String, Date>> result = new ArrayList<>();
long betweenDay = DateUtil.betweenDay(st, et, true) + 1;
for (int i = 0; i < betweenDay; i++) {
if (DateUtil.beginOfDay(st).compareTo(DateUtil.beginOfDay(et)) > 0) {
break;
} else if (st.compareTo(et) == 0) {
String last = DateUtil.format(st, ymd);
if (workDays.contains(last) || (!holidays.contains(last) && !DateTime.of(st).isWeekend())) {
Map<String, Date> map = new HashMap<>();
map.put("st", st);
map.put("et", et);
result.add(map);
}
break;
}
if (holidays.contains(DateUtil.format(st, ymd))) {
st = DateUtil.offsetDay(st, 1).toJdkDate();
} else if (workDays.contains(DateUtil.format(st, ymd))) {
Date beginT = st;
Date endT = st;
long betweenDay1 = DateUtil.betweenDay(st, et, true) + 2;
for (int j = 0; j < betweenDay1; j++) {
st = DateUtil.offsetDay(st, 1).toJdkDate();
if (holidays.contains(DateUtil.format(st, ymd))) {
Map<String, Date> map = new HashMap<>();
map.put("st", beginT);
map.put("et", endT);
result.add(map);
break;
} else if (workDays.contains(DateUtil.format(st, ymd))) {
if (st.compareTo(et) > 0) {
Map<String, Date> map = new HashMap<>();
Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
map.put("st", beginT);
map.put("et", zt);
result.add(map);
break;
}
endT = st;
} else {
if (DateTime.of(st).isWeekend()) {
Map<String, Date> map = new HashMap<>();
map.put("st", beginT);
map.put("et", endT);
result.add(map);
break;
} else {
if (st.compareTo(et) > 0) {
Map<String, Date> map = new HashMap<>();
Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
map.put("st", beginT);
map.put("et", zt);
result.add(map);
break;
}
endT = st;
}
}
}
st = DateUtil.offsetDay(endT, 2).toJdkDate();
} else {
if (DateTime.of(st).isWeekend()) {
st = DateUtil.offsetDay(st, 1).toJdkDate();
} else {
Date beginT = st;
Date endT = st;
long betweenDay1 = DateUtil.betweenDay(st, et, true) + 2;
for (int j = 0; j < betweenDay1; j++) {
st = DateUtil.offsetDay(st, 1).toJdkDate();
if (holidays.contains(DateUtil.format(st, ymd))) {
Map<String, Date> map = new HashMap<>();
map.put("st", beginT);
map.put("et", endT);
result.add(map);
break;
} else if (workDays.contains(DateUtil.format(st, ymd))) {
if (st.compareTo(et) > 0) {
Map<String, Date> map = new HashMap<>();
Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
map.put("st", beginT);
map.put("et", zt);
result.add(map);
break;
}
endT = st;
} else {
if (DateTime.of(st).isWeekend()) {
Map<String, Date> map = new HashMap<>();
map.put("st", beginT);
map.put("et", endT);
result.add(map);
break;
} else {
if (st.compareTo(et) > 0) {
Map<String, Date> map = new HashMap<>();
Date zt = DateUtil.offsetDay(st, -1).toJdkDate();
map.put("st", beginT);
map.put("et", zt);
result.add(map);
break;
}
endT = st;
}
}
}
st = DateUtil.offsetDay(endT, 2).toJdkDate();
}
}
}
return result;
}
输出结果:
还有一个计算多个时间段中重复天数的方法,有需要可以看这里:java 计算多个时间段中重复的天数