从一个时间列表中得到休息

本文关键字:列表 时间 一个 | 更新日期: 2023-09-27 18:11:24

我有一个工作项列表。每个工作项都有一个开始和结束时间。

基本上是这样的:

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点之间的时间这一事实造成了差异。

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

从一个时间列表中得到休息

创建(时间,值)对,其中值为+1表示工作开始,-1表示工作结束。然后按日期排序。迭代你得到的列表,你可以计算值的总和——当它是正数时,工作"继续"。在迭代时,标记值的总和从0到正和从正到0的时刻。你会得到不相交的间隔。

的例子:

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

给你(11日1)(1)(1)13日(15日1)(16日1)(17日1)(18日1)(19日1)

之和是(11 - 1)(2)(1)13日(15日2)(16日1)(17日0)(18日1)(19日0),

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

嗯,我曾经解决过类似的问题(不是时间,而是范围重叠)。我应用的解决方案非常简单:

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

它应该工作得很好,但是如果你有大量的数据,可能有更好的方法来解决它。这是最简单的方法(至少对我来说)。最后,您将得到一个没有重叠部分的时间列表,因此您将能够迭代列表并总结时间。