如何在List <timespan>中计算峰值和非峰值小时的总和

时间:2015-11-27 16:59:11

标签: c# linq timespan

我有List<ObjectInstance>

ObjectInstance是一个类,它有两个TimeSpan属性:StartTime和EndTimes。

开始和结束时间可以是上午8点到晚上10点之间的任何时间。在下午5点之后的任何时间都是非高峰时间,否则它是高峰时间。

我需要计算列表中的总峰值时间和总非高峰时间。

采取这种做法的最佳方法是什么?

我的方式基本上是基本的:我编写的函数类似于下面的函数,其中有很多关于peakTimeStart的条件,相对于间隔的开始和结束时间,但我觉得必须有更好的方法去做这个;也许使用LINQ或一些扩展方法来调用列表?

public static double CalculateTimeIntervalPeakHours(TimeSpan intervalStart, TimeSpan intervalEnd, TimeSpan peakTimeStart)
{
    double peakHours = 0.0;

    // some logic here to find where the interval starts & ends relative to the peakTimeStart!
    return peakHours;
}

3 个答案:

答案 0 :(得分:2)

我同意其他人关于使用datetime&amp;也考虑时区。

从技术角度来看,也许你正在寻找类似的东西 -

 var sumPeak = list.Where(timeSP => timeSP > intervalStart && timeSP < intervalEnd).Sum(item => item.Milliseconds);

如果您的逻辑不止一行,您可以使用这种语法 -

   var sumPeak = list.Where(timeSP =>
            {
                // consider this a funtion now.
              return  timeSP > intervalStart && timeSP < intervalEnd;
            })
            .Sum(item => item.Milliseconds);

包含你的逻辑超过3-4行。我建议做一个功能&amp;像这样打电话 -

 var sumPeak = list.Where(timeSP => SelectIntervals(timeSP)).Sum(item => item.Milliseconds);

  private bool SelectIntervals(TimeSpan timeSP)
    {
        throw new NotImplementedException();
    }

即使您使用日期时间,这样的表达式也会派上用场。

答案 1 :(得分:2)

假设你的课程是这样的

class ObjectInstance
{
    public TimeSpan StartTime, EndTime;
}

其中StartTime是包含的间隔开始,EndTime是间隔的唯一结尾EndTime > StartTime

首先,将Peak / OffPeak逻辑封装在类

class ObjectInstance
{
    public TimeSpan StartTime, EndTime;
    public TimeSpan PeakTime(TimeSpan peakTimeStart)
    {
        return Fit(peakTimeStart) - StartTime;
    }
    public TimeSpan OffPeakTime(TimeSpan peakTimeStart)
    {
        return EndTime - Fit(peakTimeStart);
    }
    private TimeSpan Fit(TimeSpan value)
    {
        return value < StartTime ? StartTime : value > EndTime ? EndTime : value;
    }
}

现在有了

IEnumerable<ObjectInstance> list = ...;
TimeSpan peakTimeStart = ...;

可以使用Enumerable.Aggregate

轻松计算总时间
var totalPeakTime = list.Aggregate(TimeSpan.Zero,
    (total, item) => total + item.PeakTime(peakTimeStart));
var totalOffPeakTime = list.Aggregate(TimeSpan.Zero,
    (total, item) => total + item.OffPeakTime(peakTimeStart));

计算总小时数更容易

var totalPeakHours = list.Sum(item => item.PeakTime(peakTimeStart).TotalHours);
var totalOffPeakHours = list.Sum(item => item.OffPeakTime(peakTimeStart).TotalHours);

答案 2 :(得分:-1)

时间跨度是两个DataTime对象之间的差异。您需要将TimeSpan替换为DataTime。 DateTime已经在您的计算机UTC时间内,因此无需处理夏令时。当时间输入程序或输出时,使用计算机中的TimeZone设置在UTC和本地时间之间进行转换。因此,所有数学都是使用UTC时间计算的。如果你有一个列表总时间是可以通过减去列表中的相邻索引并添加每个减法来计算,但是这应该给出与从列表中减去第一个项目相同的时间