`
lemonhandsome
  • 浏览: 9974 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

分割日期

 
阅读更多
/**
 * 将指定的时间段,减去多个指定的已用的时间段,最终返回有效的时间段
 * 整体思路就是将所有时间打散,变成集合,然后求指定时间段的补集,最终将结果中连续的时间放到一起,返回开始结束时间的列表
 * @param startDay 指定时间段的开始时间 比如1月1日
 * @param endDay 指定时间段的结束时间 比如1月30日
 * @param usedDay 指定的已用的时间段 比如[1-3到1-6],[1-18到1-20],[1-25到2-6]
 * @return 返回[1-1到1-2],[1-7到1-17],[1-21到2-24]
 */
public static List<Date[]> splitDay(Date startDay, Date endDay, List<Date[]> usedDay){
    List<Date[]> availableIntervals = new ArrayList<>();
    LocalDate startDateA = dateToLocalDate(startDay);
    LocalDate endDateA = dateToLocalDate(endDay);

    Set<LocalDate[]> dateRangesB = new HashSet<>();
    for (Date[] interval : usedDay) {
        dateRangesB.add(new LocalDate[]{dateToLocalDate(interval[0]),dateToLocalDate(interval[1])});
    }

    Set<LocalDate> dateSetA = new HashSet<>();
    for (LocalDate date = startDateA; !date.isAfter(endDateA); date = date.plusDays(1)) {
        dateSetA.add(date);
    }

    Set<LocalDate> dateSetB = new HashSet<>();
    for (LocalDate[] dateRange : dateRangesB) {
        for (LocalDate date = dateRange[0]; !date.isAfter(dateRange[1]); date = date.plusDays(1)) {
            dateSetB.add(date);
        }
    }

    // 计算补集
Set<LocalDate> complementSet = new TreeSet<>(dateSetA);
    complementSet.removeAll(dateSetB);

    // 合并连续时间段
LocalDate start = null;
    LocalDate end = null;
    for (LocalDate date : complementSet) {
        if (start == null) {
            start = date;
            end = date;
        } else if (date.isEqual(end.plusDays(1))) {
            end = date;
        } else {
            availableIntervals.add(new Date[]{localDateToDate(start),localDateToDate(end)});
            start = date;
            end = date;
        }
    }
    if (start != null && end != null) {
        availableIntervals.add(new Date[]{localDateToDate(start),localDateToDate(end)});
    }
    return availableIntervals;
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics