计算DateTimes集合之间的平均TimeSpan

本文关键字:TimeSpan 之间 DateTimes 集合 计算 | 更新日期: 2023-09-27 17:57:46

假设我们正在跟踪用户执行某个操作的时间,我们想知道这些操作之间的平均时间。

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

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

结果是2.5小时。

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

计算DateTimes集合之间的平均TimeSpan

看起来您基本上是在寻找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));

我最近有一个类似的任务,我有一个长时间运行的操作,在数千行上迭代,每行迭代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);
        }
    }

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

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;
        }
    }
}