多个时间段中筛选识别并返回重叠时间段区间【Java】

2023-06-10 10:30:55 浏览数 (1)

需求 多个时间段中,筛选出重叠的部分并返回,用于时间段重叠比较校验。

直接一个类实现。不用再建个对象来存储。支持String,Date ,LocalDate。

代码语言:javascript复制
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();
    }
}

测试类

代码语言:javascript复制
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

0 人点赞