【问题标题】:Average time from a list of start end times in linq to sql从 linq 到 sql 中的开始结束时间列表的平均时间
【发布时间】:2013-07-25 08:59:46
【问题描述】:

我有一份清单

*startTime    (datetime)
*endTime      (datetime)

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

所以我猜我需要类似的东西

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

有什么想法吗?

【问题讨论】:

    标签: c# linq timespan


    【解决方案1】:
    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);
    

    【讨论】:

    • 完美!然后简单转换为小时分钟秒
    • @DreamToCode 实际上我删除了该评论,因为我认为我误解了您计算的平均值。您是在计算每对开始/结束时间的平均值(因此您只需将两个 TickCounts 加在一起,这不会溢出)还是您想要所有时间的平均值(在这种情况下您可能会出现溢出问题)?
    • @DreamToCode 好吧,那会是个问题。由于每毫秒有 10,000 个滴答,如果在计算平均值时将所有滴答计数除以 10,000,然后将平均结果乘以 10,000,然后再将其转换回 DateTime,它应该仍然具有(大约)毫秒精度,并且它不会t 溢出如此之快(实际上快 10,000 倍;)
    • @DreamToCode 如果时间总是在同一天,您可以将其全部转换为自午夜以来的秒数,但如果时间可以跨越午夜,它会变得更加繁琐,然后会更容易只使用 DateTime.Ticks。注意:var secsSinceMidnight = (DateTime.Now - DateTime.Today).TotalSeconds;
    • @DreamToCode 我认为你可以这样做。
    【解决方案2】:

    其他答案是正确的,您可以使用简单的 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,则数据可能已记录在本地时区或其他时区的上下文中。如果您工作的时间包含夏令时转换,那么您的减法结果可能不正确。

    例如,如果您在美国太平洋时区运行此代码,并且您有 Local 种类的 DateTime,那么减去 2013-11-03 06:00 - 2013-11-03 00:00 将得到 6 小时的 TimeSpan .但实际上,7 个小时已经过去,因为那是 DST 结束的那一天,时钟在 1:00 和 2:00 之间重复这个小时。

    为避免此问题,您应该只使用 Utc 中的 DateTime 值进行数学运算,或者您应该改用 DateTimeOffset 值。

    【讨论】:

    • 好的,谢谢。基本上我只需要以秒为单位的平均值,这将是一个内部应用程序,因此 .kind 将是恒定的
    • 仅仅因为它是一个内部应用程序并不能减轻考虑这种情况的需要。我的建议是使用 DateTimeOffset。
    【解决方案3】:

    如果你有课

    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.Seconds 替换为您想要的任何内容.. 小时、分钟等... 注意:未经测试,但我认为它可能有效

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

    【讨论】:

    • 感谢您的贡献
    • 我想你的意思是.TotalSeconds,而不是.Seconds
    猜你喜欢
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 2018-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多