计算DateTimes集合之间的平均TimeSpan

时间:2011-05-27 18:34:09

标签: c# linq .net-4.0

假设我们正在跟踪用户执行某项操作的时间,并且我们想知道所述操作之间的平均时间。

例如,如果用户在以下时间执行此操作:

  • 今天下午1点
  • 今天下午3点
  • 今天下午6点

结果将是2.5小时。

我实际上已经解决了这个问题,但我觉得我的解决方案比必要的更复杂。我会把它作为答案发布。

3 个答案:

答案 0 :(得分:6)

看起来你基本上都在寻找Max - Min除以Count。

    public TimeSpan? Average
    {
        get
        {
            var diff = _dateTimes.Max().Subtract(_dateTimes.Min());
            var avgTs = TimeSpan.FromMilliseconds(diff.TotalMilliseconds / (_dateTimes.Count() - 1));
            return avgTs;
        }
    }

确保检查是否有多个DateTime。

更新:如果您使用Ticks,则更准确。

TimeSpan.FromTicks(diff.Ticks / (_dateTimes.Count() - 1));

答案 1 :(得分:3)

我最近有一个类似的任务,我有一个长时间运行的操作迭代数千行,每个行20-30次迭代。

 void LongRunningOperation()
    {
        int r = 5000;
        int sR = 20;
        List<TimeSpan> timeSpanList = new List<TimeSpan>();
        for (int i = 0; i < r; i++)
        {

            DateTime n = DateTime.Now; // Gets start time of this iteration.
            for (int x = 0; x < sR; x++)
            {
                 // DOING WORK HERE       
            }
            timeSpanList.Add(DateTime.Now - n); // Gets the length of time of iteration and adds it to list.
            double avg = timeSpanList.Select(x => x.TotalSeconds).Average(); // Use LINQ to get an average of the TimeSpan durations.
            TimeSpan timeRemaining = DateTime.Now.AddSeconds((r - i) * avg) - DateTime.Now;
            // Calculate time remaining by taking the total number of rows minus the number of rows done multiplied by the average duration.
            UpdateStatusLabel(timeRemaining);
        }
    }

答案 2 :(得分:0)

这就是我解决它的方式,但我不太喜欢它:

public class HistoryItem
{
    private IEnumerable<DateTime> _dateTimes;

    public TimeSpan? Average
    {
        get { 
            TimeSpan total = default(TimeSpan);
            DateTime? previous = null;
            int quotient = 0;
            var sortedDates = _dateTimes.OrderBy(x => x);

            foreach (var dateTime in sortedDates)
            {
                if (previous != null)
                {
                    total += dateTime - previous.Value;
                }

                ++quotient;
                previous = dateTime;
            }
            return quotient > 0 ? (TimeSpan.FromMilliseconds(total.TotalMilliseconds/quotient)) as TimeSpan? : null;
        }
    }
}