从linq中的开始-结束时间列表到sql的平均时间

本文关键字:时间 列表 sql 结束 linq 开始 | 更新日期: 2023-09-27 18:25:02

我有一个列表

*startTime    (datetime)
*endTime      (datetime)

并且需要计算出列表中所有内容的平均时间。

所以我想我需要像这样的东西

long averageTime = 
 Convert.ToInt64(listOfStartEndTimes.Average(timeSpan => timeSpan.Ticks))

有什么想法吗?

从linq中的开始-结束时间列表到sql的平均时间

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

此外,由于StartStop的值属于DateTime类型,因此您确实需要注意它们的.Kind。只有在yourDateTime.Kind == DateTimeKind.Utc

如果它们是Local类型,则结果将受到运行代码的本地计算机的时区的影响。如果它们是Unspecified,则数据可能已被记录在本地时区或某个其他时区的上下文中。如果您工作的时间包含夏令时转换,那么您的减法结果可能不正确。

例如,如果您在美国太平洋时区运行此代码,并且您有LocalDateTime,那么减去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秒。。小时、分钟等。。。注意:没有测试,但我认为它可能工作

编辑:啊,已经回答了:)