从linq中的开始-结束时间列表到sql的平均时间
本文关键字:时间 列表 sql 结束 linq 开始 | 更新日期: 2023-09-27 18:25:02
我有一个列表
*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 epoch日期):
long averageTime = listOfStartEndTimes
.Select(se => se.End - se.Start)
.Average(t => (t.Ticks – 621355968000000000) / 10000000);
其他答案是正确的,您可以使用简单的LINQ来平均TimeSpan
属性。我更喜欢让TimeSpan
类做它的工作来确定精度,就像Uffe展示的那样。但请确保您使用了正确的属性。.Seconds
将返回不适合一整分钟的剩余秒数。您需要.TotalSeconds
属性。
使用.Ticks
可能很诱人,但如果你有很多值,并且它们彼此间隔足够远,你可以很容易地得到OverflowException
。我的建议是在你的成绩中使用一个比你需要的小的单位。所以,如果你关心每分钟的平均精度,那么.TotalSeconds
应该工作得很好。然后,如果您愿意,您可以将结果返回到TimeSpan
中。
var sec = yourList.Select(p => p.Stop - p.Start).Average(p => p.TotalSeconds);
var avg = TimeSpan.FromSeconds(sec);
此外,由于Start
和Stop
的值属于DateTime
类型,因此您确实需要注意它们的.Kind
。只有在yourDateTime.Kind == DateTimeKind.Utc
。
如果它们是Local
类型,则结果将受到运行代码的本地计算机的时区的影响。如果它们是Unspecified
,则数据可能已被记录在本地时区或某个其他时区的上下文中。如果您工作的时间包含夏令时转换,那么您的减法结果可能不正确。
例如,如果您在美国太平洋时区运行此代码,并且您有Local
种DateTime
,那么减去2013-11-03 06:00
-2013-11-03 00:00
将得到6小时的TimeSpan
。但事实上,7个小时已经过去了,因为那是夏令时结束的一天,时钟在1点到2点之间重复一个小时。
为了避免这个问题,应该只使用Utc
中的DateTime
值进行计算,或者应该使用DateTimeOffset
值。
如果您有一个类
public class Time
{
public DateTime Start;
public DateTime Stop;
public Time(DateTime start, DateTime stop)
{
this.Start = start;
this.Stop = stop;
}
}
如果你用日期时间值填充,你可能会得到平均值。。。
var avg = Times.Select(p => p.Stop - p.Start).Average(p => p.Seconds);
在哪里你可以用你想要的任何东西替换p秒。。小时、分钟等。。。注意:没有测试,但我认为它可能工作
编辑:啊,已经回答了:)