时间区间计算实现
/** * 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)); } }