多个日期时间段进行合并,算出经历的时长

mac2024-03-24  34

多个日期时间段进行合并,算出经历的时长

背景描述思路代码示例

背景描述

在公司进行人员描图模块开发时,涉及到了人员参会时长和参会次数的数据,比如一个人,两个月内开了14次会议。这里面就涉及到了,如果这个人参加的两个甚至多个会议有重叠的部分,这样的时间如何通过程序去进行合并处理。

思路

我们在程序中,可以将多个时间段中的两段分别“冒泡”比较,如果有重叠,那么进行合并,将这两个段去除,将合并后的时间段加入,得到的新的时间段的列表,重复上面的过程,直到没有重叠的时间段为止(递归)

代码示例

定义一个类,类中有两个方法,getOverlapTime 和getTimeBucketList,

方法getOverlapTime:

public void getOverlapTime() throws ParseException { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); List<TimeBucket> timeBucketList = new ArrayList<TimeBucket>(); timeBucketList.add(new TimeBucket("2019-10-29 13:30:00", "2019-10-29 16:30:00")); timeBucketList.add(new TimeBucket("2019-10-29 13:30:00", "2019-10-29 17:30:00")); timeBucketList.add(new TimeBucket("2019-10-30 14:30:00", "2019-10-30 17:30:00")); timeBucketList.add(new TimeBucket("2019-10-30 15:30:00", "2019-10-30 18:30:00")); timeBucketList.add(new TimeBucket("2019-10-30 16:30:00", "2019-10-30 19:30:00")); List<TimeBucket> timeBucketList2 = getTimeBucketList(timeBucketList); for (TimeBucket timeBucket : timeBucketList2) { String format = dateFormat.format(timeBucket.getStart()); String format2 = dateFormat.format(timeBucket.getEnd()); System.out.println(format+" "+format2); } }

方法getTimeBucketList:

public List<TimeBucket> getTimeBucketList(List<TimeBucket> timeBucketList ) throws ParseException{ List<TimeBucket> myTimeBucketList = timeBucketList; DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Map<String, Integer> union = TimeBucket.union(myTimeBucketList); if(union!=null) { Integer i = union.get("i"); Integer j = union.get("j"); String start = null; String end = null; if(i.intValue()==j.intValue()) {//这条记录是多余的 TimeBucket timeBucket = myTimeBucketList.get(i); myTimeBucketList.remove(timeBucket); }else { TimeBucket timeBucket = myTimeBucketList.get(i); String startTime1 = dateFormat.format(timeBucket.getStart()); String endTime1 = dateFormat.format(timeBucket.getEnd()); TimeBucket timeBucket2 = myTimeBucketList.get(j); String startTime2 = dateFormat.format(timeBucket2.getStart()); String endTime2 = dateFormat.format(timeBucket2.getEnd()); if(startTime1.compareTo(startTime2)<=0) { start = startTime1; }else { start = startTime2; } if(endTime1.compareTo(endTime2)>=0) { end = endTime1; }else { end = endTime2; } TimeBucket bucket = new TimeBucket(start,end); myTimeBucketList.remove(timeBucket); myTimeBucketList.remove(timeBucket2); myTimeBucketList.add(bucket); } getTimeBucketList(myTimeBucketList); } return myTimeBucketList; } getTimeBucketList方法接收的是一个时间段列表,返回的是一个不存在重复时间段的时间段列表,这里最关键的是TimeBucket类,这里有找出哪个重复的时间段,在myTimeBucketList里的角标 public class TimeBucket { private static final ThreadLocal<DateFormat> FORMATS = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); private final Date start; private final Date end; public TimeBucket(Date start, Date end) { if (start.after(end)) { throw new IllegalArgumentException("时间段无效(开始日期需要小于结束日期)"); } this.start = start; this.end = end; } public TimeBucket(String start, String end) throws ParseException { this(parse(start), parse(end)); } public TimeBucket(long startTime, long endTime) { this(new Date(startTime), new Date(endTime)); } /** * TimeBucket会返回重叠的时间段 * 若返回null说明没有重叠的时间段 * * @param buckets 时间段 * @return */ public static Map<String, Integer> union(List<TimeBucket> buckets) { List<Map<String, String>> list = new ArrayList<Map<String,String>>(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //长度为1无需判断 if (buckets == null || buckets.size() <= 1) { return null; } for (int i = 0; i < buckets.size() - 1; i++) { String start = dateFormat.format(buckets.get(i).getStart()); String tempStart = start; String end = dateFormat.format(buckets.get(i).getEnd()); String tempEnd = end; for (int j = i + 1; j < buckets.size(); j++) { String start2 = dateFormat.format(buckets.get(j).getStart()); String end2 = dateFormat.format(buckets.get(j).getEnd()); if (start.compareTo(start2)<0) { start = start2; } if (end.compareTo(end2)>0) { end = end2; } if (start.compareTo(end)<0) { Map<String, Integer> map = new HashMap<String, Integer>(); map.put("i", i); map.put("j", j); return map; }else { start = tempStart; end = tempEnd; } } } return null; } public Date getStart() { return start; } public Date getEnd() { return end; } public long getStartTime() { return start.getTime(); } public long getEndTime() { return end.getTime(); } private static Date parse(String str) throws ParseException { return FORMATS.get().parse(str); } private static String format(Date str) { return FORMATS.get().format(str); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("start", format(start)) .add("end", format(end)) .toString(); } }

对getTimeBucketList进行递归,每次都会合并重复的时间段,直到不需要进行合并,结束递归,进行返回,这样就可以获取到了不重复的时间段列表,遍历获取每个时间段的开始和结束时间,进行计算即可。

最新回复(0)