需求
多个时间段中,筛选出重叠的部分并返回,用于时间段重叠比较校验。
直接一个类实现。不用再建个对象来存储。支持String,Date ,LocalDate。
import com.alibaba.fastjson2.JSON;
import com.alibaba.nacos.shaded.com.google.common.base.MoreObjects;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
/**
* 时间段重叠比较
*
* @author Diuut M Duan
*/
public class TimeBucket {
private static final ThreadLocal<DateFormat> FORMATS = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
private final Long dateId;
private final Date start;
private final Date end;
public TimeBucket(Long dateId, Date start, Date end) {
if (start.after(end)) {
throw new IllegalArgumentException("时间段无效(开始日期需要小于结束日期)");
}
this.dateId = dateId;
this.start = start;
this.end = end;
}
public TimeBucket(Date start, Date end) {
if (start.after(end)) {
throw new IllegalArgumentException("时间段无效(开始日期需要小于结束日期)");
}
this.dateId = 0L;
this.start = start;
this.end = end;
}
public TimeBucket(Long dateId, String start, String end) throws ParseException {
this(dateId, parse(start), parse(end));
}
public TimeBucket(Long dateId, LocalDate start, LocalDate end) {
this(dateId, parse(start), parse(end));
}
public TimeBucket(String start, String end) throws ParseException {
this(0L, start, end);
}
public TimeBucket(LocalDate start, LocalDate end) {
this(0L, start, end);
}
public TimeBucket(long startTime, long endTime) {
this(0L, startTime, endTime);
}
public TimeBucket(Long timeId, long startTime, long endTime) {
this(timeId, new Date(startTime), new Date(endTime));
}
/**
* TimeBucket会返回重叠的时间段
* 若返回null说明没有重叠的时间段
*
* @param buckets 时间段
* @return Set<Long> 冲突时间段ID
*/
public static Set<Long> union(TimeBucket... buckets) {
List<TimeBucket> timeVos = Arrays.asList(buckets);
Set<Long> conflictIds = new HashSet<>();
timeVos.sort(new Comparator<TimeBucket>() {
@Override
public int compare(TimeBucket t1, TimeBucket t2) {
return t1.getStart().compareTo(t2.getStart());
}
});
for (int i = 0; i < timeVos.size() - 1; i++) {
if(timeVos.get(i).getEndTime() >= timeVos.get(i+1).getStartTime() ) {
conflictIds.add(timeVos.get(i).getDateId());
conflictIds.add(timeVos.get(i+1).getDateId());
}
}
System.out.println(JSON.toJSONString(conflictIds));
return conflictIds;
}
public Long getDateId() {
return dateId;
}
public Date getStart() {
return start;
}
public Date getEnd() {
return end;
}
public long getStartTime() {
return start.getTime();
}
public long getEndTime() {
return end.getTime();
}
private static Date parse(String str) throws ParseException {
return FORMATS.get().parse(str);
}
private static Date parse(LocalDate date) {
Instant instant = date.atTime(LocalTime.MIDNIGHT).atZone(ZoneId.systemDefault()).toInstant();
return Date.from(instant);
}
private static String format(Date str) {
return FORMATS.get().format(str);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("dateId", dateId)
.add("start", format(start))
.add("end", format(end))
.toString();
}
}
测试类
import com.xxx.sdc.rwa.biz.util.TimeBucket;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.text.ParseException;
import java.util.List;
import java.util.Set;
/**
* @author Diuut M Duan
*/
@SpringBootTest
public class Tests {
@Test
public void TimeBucketTest() throws ParseException {
TimeBucket[] buckets = {
new TimeBucket(1L,"2018-01-01", "2018-01-11"),
new TimeBucket(2L,"2018-02-02", "2018-02-22"),
new TimeBucket(3L,"2018-03-03", "2018-03-11"),
new TimeBucket(4L,"2018-01-08", "2018-01-22"),
new TimeBucket(5L,"2018-02-21", "2018-02-28"),
new TimeBucket(6L,"2018-03-11", "2018-03-13"),
new TimeBucket(7L,"2018-03-14", "2018-03-15"),
new TimeBucket(8L,"2018-01-10", "2018-01-30")
};
//预期结果:1.4.8.2.5.3.6
Set<Long> union = TimeBucket.union(buckets);
System.out.println(union);
}
}
筛选处算法参考:https://blog.csdn.net/qq_41384351/article/details/114578644