c# - 如何计算许多重叠日期时间的总秒数

标签 c# datetime

我正在尝试找到一种方法来计算特定设备由于具有 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 对象列表。 code>,然后返回这个集合。如果我们这样做,那么我们可以将集合中每个项目的持续时间相加。您还可以添加一个公开 TimeLapse 对象的 Duration 的属性:

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 是一个 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")}}},
    };
}

输出

enter image description here

关于c# - 如何计算许多重叠日期时间的总秒数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54223034/

相关文章:

c# - 找不到 IdentityServer4 测试服务器

c# - ItextSharp Font.BaseFont 为某些字体返回 Null

c# - 使用 linq 填充子对象

javascript - 如何在JS中打出直播时间?

php - 将 php 日期时间值与 mysql 查询进行比较

java - 在 Java 中将日期转换为 C# 刻度

ios - 在运行时更新 iOS 应用程序时区

c# - 申请.退出

c# - .NET 中的彩色图像量化

PHP 按最大日期到最小日期对添加日期进行排序