时间区间计算实现

/**
 * Created by shun on 2020/12/3.
 * 时间区间 计算算法 实现
 * 时间段的插入
 * 时间段的删除
 */
public class IntervalAlgorithm {


    public static List<LocalDate[]> insertDate(List<LocalDate[]> intervals, LocalDate[] newInterval){
        List<long[]> insert = insert(listToArray(intervals), new long[]{newInterval[0].toEpochDay(), newInterval[1].toEpochDay()});
        return toDateList(insert);
    }

    public static List<LocalDate[]> removeDate(List<LocalDate[]> intervals, LocalDate[] toBeRemoved){
        List<long[]> removed = removeInterval(listToArray(intervals), new long[]{toBeRemoved[0].toEpochDay(), toBeRemoved[1].toEpochDay()});
        return toDateList(removed);
    }

    /**
     * 插入新的时间区间
     * @param intervals 已有区间
     * @param newInterval 新区间
     * @return 插入后的新区间
     */
    public static List<long[]> insert(long[][] intervals, long[] newInterval) {
        long left = newInterval[0];
        long right = newInterval[1];
        boolean placed = false;
        List<long[]> ansList = new ArrayList<long[]>();
        for (long[] interval : intervals) {
            if (interval[0] > right) {
                // 在插入区间的右侧且无交集
                if (!placed) {
                    addInterval(ansList, new long[]{left, right});
                    placed = true;
                }
                addInterval(ansList, interval);
            } else if (interval[1] < left) {
                // 在插入区间的左侧且无交集
                addInterval(ansList, interval);
            } else {
                // 与插入区间有交集,计算它们的并集
                left = Math.min(left, interval[0]);
                right = Math.max(right, interval[1]);
            }
        }
        if (!placed) {
            addInterval(ansList, new long[]{left, right});
        }
//        LocalDate[][] ans = new LocalDate[ansList.size()][2];
//        for (int i = 0; i < ansList.size(); ++i) {
//            ans[i] = ansList.get(i);
//        }
        return ansList;
    }


    /**
     * 删除区间
     * @param intervals
     * @param toBeRemoved
     * @return
     */
    public static List<long[]> removeInterval(long[][] intervals, long[] toBeRemoved) {
        List<long[]> res = new ArrayList();
        for (long[] inter : intervals) {
            if (inter[1] <= toBeRemoved[0] || inter[0] >= toBeRemoved[1]) {//不再区间就不变
                addInterval(res, new long[]{inter[0], inter[1]});
            } else {
                //在区间
                if (inter[0] < toBeRemoved[0] ) addInterval(res, new long[]{inter[0], toBeRemoved[0]});//右相交
                if (inter[1] > toBeRemoved[1] ) addInterval(res, new long[]{toBeRemoved[1], inter[1]});//左相交
            }
        }

        return res;
    }


    private static long[][] listToArray( List<LocalDate[]> list){
        long[][] ans = new long[list.size()][2];
        for (int i = 0; i < list.size(); ++i) {
            ans[i] = new long[]{list.get(i)[0].toEpochDay(), list.get(i)[1].toEpochDay()};
        }
        return ans;
    }

    public static List<LocalDate[]> toDateList(List<long[]> array){
        List<LocalDate[]> list = Lists.newArrayList();
        for (int i = 0; i < array.size(); i++) {
            list.add( new LocalDate[]{LocalDate.ofEpochDay(array.get(i)[0]), LocalDate.ofEpochDay(array.get(i)[1])});
        }
        return list;
    }

    //过滤掉当前时间以前的区间
    private static void addInterval(List<long[]> list, long[] newInterval){
        if (newInterval[1] > LocalDate.now().toEpochDay() ){
            if (newInterval[0] < LocalDate.now().toEpochDay()) {
                newInterval[0] = LocalDate.now().toEpochDay();
            }
            list.add(newInterval);
        }
    }


    public static void main(String[] args) {
        List<LocalDate[]> removeInterval = IntervalAlgorithm.removeDate(
                Lists.newArrayList(
                        new LocalDate[]{LocalDate.of(2019, 01, 01), LocalDate.of(2020, 03, 01)},
                        new LocalDate[]{LocalDate.of(2021, 01, 01), LocalDate.of(2021, 03, 01)},
                        new LocalDate[]{LocalDate.of(2021, 05, 01), LocalDate.of(9999, 01, 01)}
                        ),
                new LocalDate[]{LocalDate.of(2021, 06, 01), LocalDate.of(9999, 01, 01)}
        );

        System.out.println(JSON.toJSONString(removeInterval));


        List<LocalDate[]> insert = IntervalAlgorithm.insertDate(
                removeInterval,
                new LocalDate[]{LocalDate.of(2021, 06, 01), LocalDate.of(9999, 01, 01)});


        System.out.println(JSON.toJSONString(insert));
    }

}

 

posted @ 2020-12-28 15:09  然_默  阅读(442)  评论(0编辑  收藏  举报