c# - 如何计算许多重叠日期时间的总秒数
问题描述
我正在尝试找到一种方法来计算特定设备由于具有 StartTime 和 EndTime 的不同类型的错误而出现故障的总秒数,并且可能发生在同一时刻但持续时间不同。
那是我拥有的 DateTimes 的集合:
private class TimeLapse
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
Dictionary<string, List<TimeLapse>> _devices = new Dictionary<string, List<TimeLapse>>();
其中字典中的字符串是设备的名称;
但我不知道从哪里开始不构建一个令人作呕的代码来做到这一点。有人有同样的问题要解决吗?
解决方案
做到这一点的一种方法是使用附加方法扩展您的类,该方法将合并TimeLapse
对象列表,方法是将任何重叠的对象组合成一个TimeLapse
,然后返回这个集合。如果我们这样做,那么我们可以将集合中每个项目的持续时间相加。您还可以添加一个公开对象Duration
的TimeLapse
属性:
private class TimeLapse
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public TimeSpan Duration => (EndTime - StartTime).Duration();
public static List<TimeLapse> Merge(List<TimeLapse> items)
{
if (items == null || items.Count < 2) return items;
var results = new List<TimeLapse>();
foreach (var item in items)
{
var overlappingItem = results.FirstOrDefault(item.OverlapsWith);
if (overlappingItem == null) results.Add(item);
else overlappingItem.CombineWith(item);
}
return results;
}
private bool OverlapsWith(TimeLapse other)
{
return other != null &&
other.StartTime <= EndTime &&
other.EndTime >= StartTime;
}
private void CombineWith(TimeLapse other)
{
if (!OverlapsWith(other)) return;
if (other.StartTime < StartTime) StartTime = other.StartTime;
if (other.EndTime > EndTime) EndTime = other.EndTime;
}
}
下面是一个示例,说明如何显示字典中每个项目的持续时间。
我包含了一种生成设备虚拟列表的方法,所以我使用Days
它是因为它更容易编写和验证结果是否正确,但由于Duration
是 a TimeSpan
,你可以获得几乎任何你想要的测量单位(比如TotalSeconds
在你的情况下):
private static void Main()
{
Dictionary<string, List<TimeLapse>> devices = GetDeviceList();
foreach (var device in devices)
{
Console.WriteLine("{0}: {1} total days", device.Key,
TimeLapse.Merge(device.Value).Sum(value => value.Duration.TotalDays));
}
GetKeyFromUser("Done! Press any key to exit...");
}
private static Dictionary<string, List<TimeLapse>> GetDeviceList()
{
return new Dictionary<string, List<TimeLapse>>
{
// device1 total should be 4 days (1/1 - 1/5)
{"device1", new List<TimeLapse>{
new TimeLapse {StartTime = DateTime.Parse("1/1/2019"),
EndTime = DateTime.Parse("1/3/2019")},
new TimeLapse {StartTime = DateTime.Parse("1/2/2019"),
EndTime = DateTime.Parse("1/3/2019")},
new TimeLapse {StartTime = DateTime.Parse("1/3/2019"),
EndTime = DateTime.Parse("1/5/2019")}}},
// device2 total should be 7 days (1/1 - 1/4 plus 1/6 - 1/10)
{"device2", new List<TimeLapse>{
new TimeLapse {StartTime = DateTime.Parse("1/1/2019"),
EndTime = DateTime.Parse("1/3/2019")},
new TimeLapse {StartTime = DateTime.Parse("1/3/2019"),
EndTime = DateTime.Parse("1/4/2019")},
new TimeLapse {StartTime = DateTime.Parse("1/6/2019"),
EndTime = DateTime.Parse("1/10/2019")}}},
// device3 total should be 2 days (1/1 - 1/2 plus 1/6 - 1/7)
{"device3", new List<TimeLapse>{
new TimeLapse {StartTime = DateTime.Parse("1/1/2019"),
EndTime = DateTime.Parse("1/2/2019")},
new TimeLapse {StartTime = DateTime.Parse("1/6/2019"),
EndTime = DateTime.Parse("1/7/2019")}}},
// device4 total should be 2 days (1/1 - 1/3)
{"device4", new List<TimeLapse>{
new TimeLapse {StartTime = DateTime.Parse("1/1/2019"),
EndTime = DateTime.Parse("1/3/2019")}}},
};
}
输出
推荐阅读
- java - 如何使用 Jackson 启用 JSR310 对 LocalDate 的支持?
- r - DT::DataTables 中第一列的黑色背景和白色字体
- html - 更改日期时如何显示总和的一行?
- azure-storage - 使用数据工厂根据 Datetimestamp 列从存储帐户中选择文件
- python - 具有嵌套类的类的 Python 行为
- python - Django:只提交一个用for循环创建的表单
- macos - 使用 M1 在 Mac 上安装谷歌应用引擎启动器
- software-design - 控制流程图与流程图?
- concurrency - BPM 引擎和共享状态
- typescript - “PromiseConstructor”类型的 ts-loader 上不存在属性“allSettled”