定义一个完整时间段: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: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
已知一个区间 [a, b]
将其减去另一个区间 [c, d]
求得到的一个或两个新区间: [x1, y1] 和 [x2, y2]
不考虑高效率的话,循环调用该函数就行了。
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;
}
}
* 整数区域减法计算: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] };
}
}
之前稍微想了下,用链表来做可能批处理效果会好些,不过还是比较懒,今天上来看已经结贴,估计楼主也算搞定了。