效果1:判断区间重叠
TimeInterval t1 = new TimeInterval("12:00", "22:00", StringSwitchLocalTimeUtil::getLocalTimeToColon);
TimeInterval t2 = new TimeInterval("23:00", "23:59", StringSwitchLocalTimeUtil::getLocalTimeToColon);
List<TimeInterval> list = Arrays.asList(t1, t2);
TimeIntervalUtil.verifyTime(list);
TimeInterval t3 = new TimeInterval("09:00:00", "11:00:00", StringSwitchLocalTimeUtil::getLocalTimeToColon);
TimeInterval t4 = new TimeInterval(Time.valueOf("10:00:00"), Time.valueOf("11:00:00"));
List<TimeInterval> list1 = Arrays.asList(t1, t2 , t3 , t4);
TimeIntervalUtil.verifyTime(list1);
效果2:校验结束时间和开始时间的值
TimeInterval t1 = new TimeInterval("12:00", "11:00", StringSwitchLocalTimeUtil::getLocalTimeToColon);
直接上代码:
import lombok.Getter;
import java.sql.Time;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
/**
* <p>
* 时间区间工具类
* </p>
*
* @author wxm
* @Date 2021/6/17
*/
public class TimeIntervalUtil {
private TimeIntervalUtil(){}
/**
* 校验时间是否有重叠
* @param list 对比的时间集合
*/
public static void verifyTime(List<TimeInterval> list){
//排序 用开始时间进行排序
list.sort(Comparator.comparing(TimeInterval::getTimeStart));
//双重循环判断时间是否重叠
for (TimeInterval timeInterval : list) {
LocalTime timeStart = timeInterval.getTimeStart();
LocalTime timeEnd = timeInterval.getTimeEnd();
String uuid = timeInterval.getUuid();
for (TimeInterval interval : list) {
String uuid1 = interval.getUuid();
//利用uuid判断两个时间是否是同一个
if (!uuid.equals(uuid1)){
LocalTime timeStart1 = interval.getTimeStart();
LocalTime timeEnd1 = interval.getTimeEnd();
//不是同一个 对比时间区间 如12:00-18:00 比 17:00-18:00 那就是区间重叠 9:00-14:59 14:00-18:59
boolean before = timeStart.isBefore(timeStart1) || timeStart.equals(timeStart1);//外层开始时间在内层开始时间前 或者 内外层开始时间相同
boolean after = timeEnd.isAfter(timeEnd1) || timeEnd.equals(timeEnd1);//外层结束时间在内层结束时间后 或者 内外层结束时间相同
boolean all = timeEnd.isAfter(timeStart1) && timeEnd1.isAfter(timeEnd); //外层的结束时间 是否 在内层开始时间后 并且 内层结束时间在外层结束时间前
if ((before && after) || all){
R.exception(timeInterval + "与" + interval + "有重叠");
}
}
}
}
}
/**
* 字符串转换LocalTime 工具类
*/
public static class StringSwitchLocalTimeUtil {
/**
* 根据:进行拆分字符串 在转换为LocalTime
* @param timeStr 待拆分的字符串
* @return LocalTime
*/
public static LocalTime getLocalTimeToColon(String timeStr){
return getLocalTime(timeStr,item -> item.split(":"));
}
/**
* 拆分
* @param timeStr 拆分的字符串
* @param splitFunction 拆分规则
* @return LocalTime
*/
public static LocalTime getLocalTime(String timeStr,Function<String,String[]> splitFunction) {
try {
String[] split = splitFunction.apply(timeStr);
if (split.length == 1){
return LocalTime.of(Integer.parseInt(split[0]),0);
}else if (split.length == 2){
return LocalTime.of(Integer.parseInt(split[0]),Integer.parseInt(split[1]));
}else if (split.length == 3){
return LocalTime.of(Integer.parseInt(split[0]),Integer.parseInt(split[1]),Integer.parseInt(split[2]));
}else {
return LocalTime.now();
}
}catch (Exception e){
R.exception("时间解析失败 " + timeStr);
}
return null;
}
}
/**
* 时间容器类
*/
public static class TimeInterval{
public TimeInterval(String timeStartStr, String timeEndStr, Function<String,LocalTime> getLocalTimeFunction){
this.timeStart = getLocalTimeFunction.apply(timeStartStr);
this.timeEnd = getLocalTimeFunction.apply(timeEndStr);
this.checkTimeNull();
this.checkTimeSize();
}
public TimeInterval(Time timeStar,Time timeEnd){
this.timeStart = timeStar.toLocalTime();
this.timeEnd = timeEnd.toLocalTime();
this.checkTimeNull();
this.checkTimeSize();
}
public TimeInterval(Date dateStar,Date dateEnd){
this.timeStart = LocalDateTime.ofInstant(dateStar.toInstant(), ZoneId.systemDefault()).toLocalTime();
this.timeEnd = LocalDateTime.ofInstant(dateEnd.toInstant(), ZoneId.systemDefault()).toLocalTime();
this.checkTimeNull();
this.checkTimeSize();
}
/**
* 校验时间大小
* 结束时间 不能小于 开始时间
*/
private void checkTimeSize(){
if (timeEnd.isBefore(timeStart)){
R.exception("结束时间 [" +timeEnd+ "] 不能小于开始时间 ["+ timeStart +"]");
}
}
/**
* 校验时间空值
*/
private void checkTimeNull(){
if (timeEnd == null){
R.exception("开始时间不能为空");
}
if (timeStart == null){
R.exception("开始时间不能为空");
}
}
//开始时间
@Getter
private final LocalTime timeStart;
//结束时间
@Getter
private final LocalTime timeEnd;
//该时间唯一标识
@Getter
private final String uuid = UUID.randomUUID().toString();
@Override
public String toString() {
return "{" +
"开始时间=" + timeStart +
", 结束时间=" + timeEnd +
'}';
}
}
}
public static void exception(String msg) {
throw new RuntimeException(msg);
}
说明:
- TimeInterval中uuid用做当前时间区间的唯一标识(可以换做其他的)
- StringSwitchLocalTimeUtil.getLocalTimeToWhipptree(String str) 可以对getLocalTimeTo类进行拓展加入其他拆分方法
//根据 - 进行拆分
public static LocalTime getLocalTimeToWhipptree(String timeStr){
return getLocalTime(timeStr,item -> item.split("-"));
}
StringSwitchLocalTimeUtil.getLocalTime(item, timeStr -> timeStr.split("_"))
- TimeInterval中拓展构造方法 即可以支持更多不同的开始时间和结束时间