C# 从时间列表中获得休息

C# 从时间列表中获得休息,c#,algorithm,datetime,time,timespan,C#,Algorithm,Datetime,Time,Timespan,我有一份工作项目清单。每个工作项都有一个开始时间和一个结束时间 所以,基本上看起来是这样的: 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)); 这只是总数 但现在它变得困难了:如果我想提取平行时间,我该如何计算这个总和 例如: 是6.5小时,但总和是7.

我有一份工作项目清单。每个工作项都有一个开始时间和一个结束时间

所以,基本上看起来是这样的:

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));
这只是总数

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

例如:

是6.5小时,但总和是7.5小时。事实上,两个工作项映射到10点和11点之间的时间会产生差异

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

创建(时间、值)对,其中值为+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)(15,2)(16,1)(17,0)(18,1)(19,0)


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

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

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

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

    是否有设置的间隔(例如,最小间隔为0.5小时)?如果是这样的话,一个简单的方法就是检查每半个小时的工作项,然后把它们全部加起来。不幸的是,时间完全是任意的,可能从几秒钟到几天不等。我现在使用这个库解决了这个问题:简单、直接、有效:-),也要小心模棱两可的时候。您使用的
    DateTime
    值具有
    .Kind==未指定的
    。如果这些是UTC提供的,您就可以了。如果它们来自某个本地时区,那么在跨越夏令时转换时,您的数学可能会出错。如果不能使用UTC,则应使用
    DateTimeOffset
    。一般来说,“未指定”或“本地”
    DateTime
    值对于数学来说是不安全的。示例代码:如果您愿意,可以随意编辑您的答案。我实现了它,它工作得非常完美:-)谢谢您的提示!感谢您提供的示例,我看到这一点太晚了,但现在我将比较您的解决方案和我的解决方案,并从两者中取其精华:-)
    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