计算TimeSpans集合的平均值

60
我有一个TimeSpan的集合,它们代表执行任务所花费的时间。现在我想找到执行该任务的平均时间。这应该很容易,但出于某种原因,我没有得到正确的平均值。
这是我的代码:
private TimeSpan? GetTimeSpanAverage(List<TimeSpan> sourceList)
{
    TimeSpan total = default(TimeSpan);

    var sortedDates = sourceList.OrderBy(x => x);

    foreach (var dateTime in sortedDates)
    {
        total += dateTime;
    }
    return TimeSpan.FromMilliseconds(total.TotalMilliseconds/sortedDates.Count());
}

请提供样本数据以及您得到的结果和期望的结果。顺便说一句,顺序并不重要。 - Daniel Hilgarth
3个回答

109

您可以使用接受long类型集合作为参数的平均值重载

double doubleAverageTicks = sourceList.Average(timeSpan => timeSpan.Ticks);
long longAverageTicks = Convert.ToInt64(doubleAverageTicks);

return new TimeSpan(longAverageTicks);

这给了我一个错误:无法将“double”转换为“long”。 - hs2d
1
дҪ еҸҜд»ҘдҪҝз”ЁTotalSecondsд»ЈжӣҝTicksпјҢ然еҗҺдҪҝз”ЁTimeSpan.FromSecondsгҖӮ - V4Vendetta
@V4Vendetta 是的,你可以这样做,但是你会失去亚秒级别的组件,如果你计时短动作的话,这些组件可能很有用。 - vc 74
@vc74 如果是这样的话,您可以使用TotalMilliseconds。在您的情况下,您将double转换为long,因此在这种情况下也会发生损失 :) - V4Vendetta
@V4Vendetta 是的,但只有在计算出平均值后才能进行,这比每个时间段都要好。 - vc 74

12
var average = new TimeSpan(sourceList.Select(ts => ts.Ticks).Average());

注意,你的方法返回一个Nullable,但是不需要,除非你想在源列表为空时返回null,在这种情况下,请先进行单独检查。

5
目前没有返回long类型值的 Enumerable.Average() 重载方法,同时也没有接受double类型参数的TimeSpan构造函数,所以这个示例对我来说无法通过编译。为了使其编译通过,我不得不添加一个显式转换 (long) 来转换参数:var average = new TimeSpan((long)sourceList.Select(ts => ts.Ticks).Average()); - Konard

4
除了上面的答案,我建议你在秒级或毫秒级上取平均值(取决于你的要求)。
sourceList.Average(timeSpan => timeSpan.ToTalMilliseconds)

现在,您可以使用此值来计算新的TimeSpan,方法如下:

TimeSpan avg = TimeSpan.FromMilliseconds(double value here)

2
我只想警告大家,如果你的平均值甚至不到一毫秒,那么由于某些精度问题,你的新平均TimeSpan将始终为0。 - Artholl
@Artholl 那正是我的问题。 - Paul C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接