定义一个完整时间段:2012-12-29 08:00:00至2012-12-29 20:59:59    定义若干个被占用的时间段如:
    时间段1:2012-12-29 09:00:00 至 2012-12-29 10:30:00   
    时间段2:2012-12-29 15:00:00 至 2012-12-29 17:00:00
    .....................
    .....................
    在完整时间段基础上需求出剔除时间段1,2(已经被占用)的空闲时间段Java

解决方案 »

  1.   

    自己写代码实现吧,设计算法时,不要特意强调“时间”概念。将其全部转为毫秒(或秒),那么问题就变成了,编写函数如下:
      已知一个区间 [a, b]
      将其减去另一个区间 [c, d]
      求得到的一个或两个新区间: [x1, y1] 和 [x2, y2]
    不考虑高效率的话,循环调用该函数就行了。
      

  2.   

    将空闲的开始时间和结束时间封装成对象,放在list集合中就行
      

  3.   

    效率不知道怎么样???import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Set;
    import java.util.TreeSet;public class Sd123 { static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public static void main(String[] args) throws Exception { MyDate m = new MyDate();
    m.setStartDate("2012-12-29 08:00:00");
    m.setEndDate("2012-12-29 20:59:59"); MyDate m1 = new MyDate();
    m1.setStartDate("2012-12-29 09:00:00");
    m1.setEndDate("2012-12-29 10:30:00 "); MyDate m2 = new MyDate();
    m2.setStartDate("2012-12-29 15:00:00");
    m2.setEndDate("2012-12-29 17:00:00"); List<MyDate> l = new ArrayList<MyDate>();
    l.add(m1);
    l.add(m2); List<MyDate> r = getFreeTime(m, l);
    for (MyDate d : r) {
    System.out.println(d.getStartDate() + " ~ " + d.getEndDate());
    }
    } private static List<MyDate> getFreeTime(MyDate m, List<MyDate> busy) throws Exception { long start = sdf.parse(m.getStartDate()).getTime() / 1000L;
    long end = sdf.parse(m.getEndDate()).getTime() / 1000L;
    Set<Long> all = new TreeSet<Long>();
    for (long i = start; i <= end; i++) {
    all.add(i);
    }
    Set<Long> busySet = new TreeSet<Long>();
    for (MyDate my : busy) {
    long s = sdf.parse(my.getStartDate()).getTime() / 1000L;
    long e = sdf.parse(my.getEndDate()).getTime() / 1000L;
    for (long i = s; i <= e; i++) {
    busySet.add(i);
    }
    }
    all.removeAll(busySet);
    List<Long> free = new ArrayList<Long>(all);
    List<MyDate> r = new ArrayList<MyDate>();
    MyDate mm = new MyDate();
    for (int i = 0; i < free.size(); i++) { long c = free.get(i);
    if (i == 0) {
    mm.setStartDate(sdf.format(new Date(c * 1000)));
    }
    if (i == free.size() - 1) {
    mm.setEndDate(sdf.format(new Date(c * 1000)));
    r.add(mm);
    break;
    }
    long n = free.get(i + 1);
    if (n > c + 1) {
    mm.setEndDate(sdf.format(new Date(c * 1000)));
    r.add(mm);
    mm = new MyDate();
    mm.setStartDate(sdf.format(new Date(n * 1000)));
    }
    }
    return r;
    }
    }class MyDate { String startDate; String endDate; public String getEndDate() {
    return endDate;
    } public void setEndDate(String endDate) {
    this.endDate = endDate;
    } public String getStartDate() {
    return startDate;
    } public void setStartDate(String startDate) {
    this.startDate = startDate;
    }
    }
      

  4.   

    4楼这个程序,如果时间跨度大点的话,内存和CPU怕是都撑不住
      

  5.   

    以一天为例,先假设空余时间段为00:00到该天结束,然后找所有非空余时间段的开始时间最小的假设为A1,第一个空余时间段就是00:00-A1,第二个空余时间段为A2(开始时间最小的结束时间),然后再找除A1外最小的开始时间B1,第二个空余时间段为:A2-B1,如此类推。个人愚见,可不采纳。
      

  6.   

        /**
         * 整数区域减法计算:as - bs
         * @param as 区域,数组长度为2的整型,0为起始值,1为结束值
         * @param bs 区域,数组长度为2的整型,0为起始值,1为结束值
         * @return 结果区域,偶数下标为起始值,奇数下标为结束值,数组长度可能为0、2、4
         */
        public static long[] rangeMinus(long[] as, long[] bs) {
            System.out.println(as[0] + "," + as[1] + " - " + bs[0] + "," + bs[1]);
            if (bs[0] > as[1] || bs[1] < as[0]) {
                return as;
            } else if (bs[0] == as[0] && bs[1] == as[1]) {
                return new long[0];
            } else if (bs[0] <= as[0]) {
                return new long[] { bs[1] + 1, as[1] };
            } else if (bs[1] >= as[1]) {
                return new long[] { as[0], bs[0] - 1 };
            } else {
                return new long[] { as[0], bs[0] - 1, bs[1] + 1, as[1] };
            }
        }
    之前稍微想了下,用链表来做可能批处理效果会好些,不过还是比较懒,今天上来看已经结贴,估计楼主也算搞定了。