我有一个清单
*startTime (datetime)
*endTime (datetime)
并且需要计算出列表中所有内容的平均时间。
所以我猜我需要类似的东西
long averageTime =
Convert.ToInt64(listOfStartEndTimes.Average(timeSpan => timeSpan.Ticks))
有任何想法吗?
long averageTime = listOfStartEndTimes
.Select(se => se.End - se.Start)
.Average(t => t.Ticks);
或者,使用稍低的分辨率(unix 纪元日期代替):
long averageTime = listOfStartEndTimes
.Select(se => se.End - se.Start)
.Average(t => (t.Ticks – 621355968000000000) / 10000000);
其他答案是正确的,您可以TimeSpan
使用简单的 LINQ 平均属性。我更喜欢让TimeSpan
班级来确定精度,例如 Uffe 所展示的。但请确保您使用的是正确的属性。 .Seconds
将返回不适合整分钟的剩余秒数。你想要的.TotalSeconds
财产。
使用.Ticks
可能很诱人,但OverflowException
如果你有很多值并且它们之间的距离足够远,你可以很容易地得到一个。我的建议是在结果中使用比您需要的小一个单位。因此,如果您关心精确到分钟的平均精度,那么.TotalSeconds
应该可以很好地工作。然后,您可以根据需要将结果带回 aTimeSpan
中。
var sec = yourList.Select(p => p.Stop - p.Start).Average(p => p.TotalSeconds);
var avg = TimeSpan.FromSeconds(sec);
另外,由于您的Start
和Stop
值是 type DateTime
,那么您确实需要注意它们的.Kind
. 只有在 时才能保证这样的操作是准确的yourDateTime.Kind == DateTimeKind.Utc
。
如果它们是Local
种类,那么结果将受到运行代码的本地计算机的时区的影响。如果是Unspecified
,则数据可能已记录在本地时区或其他时区的上下文中。如果您工作的时间涵盖夏令时转换,那么您的减法结果可能不正确。
例如,如果您在美国太平洋时区运行此代码,并且您有Local
多种DateTime
,那么减去2013-11-03 06:00
-2013-11-03 00:00
将给您TimeSpan
6 小时。但实际上,已经过了 7 个小时,因为那是 DST 结束的那一天,时钟在 1:00 和 2:00 之间重复这个小时。
为避免此问题,您应该只对 中的DateTime
值进行数学运算Utc
,或者您应该使用DateTimeOffset
值来代替。
If you have a class
public class Time
{
public DateTime Start;
public DateTime Stop;
public Time(DateTime start, DateTime stop)
{
this.Start = start;
this.Stop = stop;
}
}
That you fill with datetime values you can probably get the average with...
var avg = Times.Select(p => p.Stop - p.Start).Average(p => p.Seconds);
Where you can replace p.Seconds with whatever you would like.. Hours, minutes etc... Note: Not tested, but I think it might work
Edit: Ahh, already answered :)