2013-04-30 34 views
5

我有一个工作项目清单。每个工作项目都有一个开始和结束时间。从列表中获取休息时间

所以,基本上它看起来像这样:

List<Work> works = new List<Work>(); 
works.Add(new Work(
    new DateTime(2013, 4, 30, 9, 0, 0), 
    new DateTime(2013, 4, 30, 11, 0, 0)); 

现在,我想这是工作的总时间。再次,基本上这很容易:

09:00-11:00 => 2 hours 
13:00-17:00 => 4 hours 
---- 
06:00 hours 

这只是总和。

但现在变得困难了:如果我想提取平行时间,我该如何计算这个总和?

例如,

09:00-11:00 => 2 hours 
10:00-11:30 => 1.5 hours 
13:00-17:00 => 4 hours 
---- 
06:30 hours 

为6.5小时,但总和是7.5小时。两个工作项目映射到10点到11点之间的事实造成了不同。

我该如何解决这个问题,可以基本上以任何可能的方式相互重叠的任意数量的工作项目(周边,开始重叠,结束重叠,包括)?

+0

是否有设定的时间间隔(例如最小0.5小时)?如果是这样,一个简单的方法是检查每个半小时的插槽周围的工作项目,并将其全部添加。 – 2013-04-30 09:13:55

+0

不幸的是,时间完全是任意的,可能从几秒到几天不等。 – 2013-04-30 09:20:41

+1

我现在用这个库解决了它:简单,直接,而且正常工作:-) – 2013-04-30 10:54:48

回答

5

创建(时间,值)对,其中值为+1开始工作和-1结束。然后按日期对这些对进行排序。迭代你得到的清单,你可以计算出价值的总和 - 当它是积极的,工作是“继续”。在迭代过程中,标记值的总和从0到正值,从正值到0的时刻。您将得到不相交的间隔。

实施例:

11 - 13, 12 - 16, 15 - 17, 18 - 19

给你(11,1)(12,1)(13 - 1)( 15,1)(16,-1)(17,-1)(18,1)(19,-1)

(11,1)(12,2)(13 1) ,2)(16,1)(17,0)(18,1)(19,0),

所以不相交的周期是(11,17)和(18,19)

+2

示例代码:http://pastebin.com/KnhRwrsX如果需要,请随意编辑到您的答案中。 – 2013-04-30 09:27:58

+0

我实现了它,它完美地工作:-) 感谢您的提示! – 2013-04-30 09:43:16

+0

谢谢你的样品,我看到这个太晚了,但现在我会比较你的VS我的解决方案,并采取两个最好的:-)) – 2013-04-30 09:43:55

2

嗯,我曾经解决类似的问题(与时间不一样,但与范围重叠)。解决方案我施加的是非常简单的:按升序

    1. 排序元素从第一个元素开始,看它是否有下一个元素重叠
    2. 如果是 - 重新处理元素,提取overlaping部分作为新元素,修改旧元素之前结束/开始重叠期间
    3. 插入在两者之间旧元素新创建的元素
    4. 继续处理

    它应该正常工作,但是如果你有大量的数据可能有更好的方法来解决它。这只是最简单的方法(至少对我而言)。您将最终得到没有重叠部分的时间列表,因此您只需遍历列表并总结时间即可。