C# 如何计算C语言中某些时间间隔的平均值#
我已经搜索了这个问题,但不幸的是找不到正确的答案 我想计算在10个不同的日子里花在做某事上的平均时间,我有10个C# 如何计算C语言中某些时间间隔的平均值#,c#,datetimepicker,timespan,C#,Datetimepicker,Timespan,我已经搜索了这个问题,但不幸的是找不到正确的答案 我想计算在10个不同的日子里花在做某事上的平均时间,我有10个datetimepicker作为开始时间,还有10个datetimepicker作为每天的结束时间(总共20个datetimepicker) 现在我想得到这10天内平均工作时间 这就是我每天计算timespan所做的,现在我不知道如何计算这些timespan 我当然想知道有没有更快捷的方法来完成这项工作 DateTime Dt1 = dateTimePicker1.Value; Dat
datetimepicker
作为开始时间,还有10个datetimepicker
作为每天的结束时间(总共20个datetimepicker
)
现在我想得到这10天内平均工作时间
这就是我每天计算timespan
所做的,现在我不知道如何计算这些timespan
我当然想知道有没有更快捷的方法来完成这项工作
DateTime Dt1 = dateTimePicker1.Value;
DateTime Dt2 = dateTimePicker2.Value;
.
.
.
DateTime Dt20 = dateTimePicker20.Value;
TimeSpan Day1 = DateTime.Parse(Dt11.TimeOfDay.ToString()).Subtract(DateTime.Parse(Dt1.TimeOfDay.ToString()));
TimeSpan Day2 = DateTime.Parse(Dt12.TimeOfDay.ToString()).Subtract(DateTime.Parse(Dt2.TimeOfDay.ToString()));
.
.
.
TimeSpan Day10 = DateTime.Parse(Dt20.TimeOfDay.ToString()).Subtract(DateTime.Parse(Dt10.TimeOfDay.ToString()));
我想找到第1天到第10天的平均值给定一个
IEnumerable
,您可以使用此扩展方法对其进行平均:
public static TimeSpan Average(this IEnumerable<TimeSpan> spans) => TimeSpan.FromSeconds(spans.Select(s => s.TotalSeconds).Average());
现在计算平均值:
var avgDurs = durs.Average();
PS:创建了@MattJohnson答案的汇总版本:
public static TimeSpan Mean(this IEnumerable<TimeSpan> source) => TimeSpan.FromTicks(source.Aggregate((m: 0L, r: 0L, n: source.Count()), (tm, s) => {
var r = tm.r + s.Ticks % tm.n;
return (tm.m + s.Ticks / tm.n + r / tm.n, r % tm.n, tm.n);
}).m);
publicstatictimespan-Mean(这个IEnumerable源)=>TimeSpan.FromTicks(source.Aggregate((m:0L,r:0L,n:source.Count()),(tm,s)=>{
var r=tm.r+s.Ticks%tm.n;
返回值(tm.m+s.Ticks/tm.n+r/tm.n,r%tm.n,tm.n);
})(1.m);
您可以通过基于刻度数实例化新的时间跨度来找到平均值
var time_spans = new List<TimeSpan>() { new TimeSpan(24, 10, 0), new TimeSpan(12, 0, 45), new TimeSpan(23, 30, 0), new TimeSpan(11, 34, 0) };
var average = new TimeSpan(Convert.ToInt64(time_spans.Average(t => t.Ticks)));
Console.WriteLine(average);
var time_span=new List(){new TimeSpan(24,10,0),new TimeSpan(12,0,45),new TimeSpan(23,30,0),new TimeSpan(11,34,0)};
var average=新的时间跨度(转换为64(时间跨度平均值(t=>t.Ticks));
控制台写入线(平均值);
结果17:48:41.2500000
为了跟进NetMage完美的答案,请注意,他的平均值
扩展方法是使用.TotalSeconds
,它返回整数秒和分数秒的双精度,毫秒精度。如果您从时间选择器获取值,这可能很好,但在一般情况下,这将导致精度的轻微损失
此外,TimeSpan.FromSeconds
方法在处理大值时可能会溢出。即使在不求平均值的情况下,也可以复制:
TimeSpan.FromSeconds(TimeSpan.MaxValue.TotalSeconds) // will throw an OverflowException
帕特里克·霍夫曼(Patrick Hofman)在评论中提出了一个很好的观点,即从秒切换到滴答声也可能导致溢出,因此需要另一种解决方案
采用中给出的技术,我们可以使用一种方法计算TimeSpan
值集合的平均值,而不会损失精度和溢出:
public static TimeSpan Mean(this ICollection<TimeSpan> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
long mean = 0L;
long remainder = 0L;
int n = source.Count;
foreach (var item in source)
{
long ticks = item.Ticks;
mean += ticks / n;
remainder += ticks % n;
mean += remainder / n;
remainder %= n;
}
return TimeSpan.FromTicks(mean);
}
如果你有一个数组或一个列表,而不是20个独立的变量,那会容易得多。(也不清楚为什么要格式化TimeSpan
值,然后重新对它们进行排序。)将它们全部相加,然后除以数字。正如斯基特所说,把它们放在一个数组里,我很好奇。为什么您决定创建一个字符串只是为了再次解析它?我真的对你的动机很感兴趣,因为我一直看到这种方法,它从来都不是必需的,也不是可取的。另外,你是否保证所有的价值观对都在同一天?或者你可以有一双跨越午夜的,比如晚上11点到凌晨1点之间的两个小时?如果所有的约会时间都有相同的日期,为什么要去掉它?无论如何,你只对差异感兴趣。所以var MyTimeSpan=myDateTime1-myDateTime2
似乎在没有TimeOfDay
或ToString()
的情况下完成了这项任务(最后一项毫无用处,但由于某些原因非常常见)。最好使用滴答声而不是秒,以免丢失更精确的任何信息。虽然在OP的情况下,可能不重要,但是来自选择器控件,如果要保留扩展方法,则希望它在各种情况下都可用。@MattJohnson添加勾号可能会在溢出时成为问题。秒是一个更好的选择。谢谢,但我得到了这个错误:'List'不包含“Average”的定义,而最佳扩展方法重载“Queryable.Average(IQueryable)”需要一个类型为“IQueryable”的接收器
使用System.Linq添加此代码>@patrickhoffman-没错,但有一些方法可以用来克服这一点。虽然在这个特殊的情况下我同意你的看法谢谢,负刻度怎么办?如果它们为负值,我如何检查它们并将它们乘以-1?不需要额外的代码来处理负值。这里的所有内容都已签名。似乎是进行复杂的聚合的好时机。顺便说一句,为什么我们使用ICollection
而不是IEnumerable
?为了避免由于必须调用.Count()
而可能出现的两次枚举,我在IEnumerable
上创建了一个Aggregate
版本(不是所有IEnumerable
实现ICollection
),有趣的是平均值
(5,10,15)与平均值相比,秒返回的结果稍差,尽管在7时间跨度
s的样本中,平均值
更准确。请注意,TimeSpan
seconds精确到毫秒。
public static TimeSpan Mean(this ICollection<TimeSpan> source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
long mean = 0L;
long remainder = 0L;
int n = source.Count;
foreach (var item in source)
{
long ticks = item.Ticks;
mean += ticks / n;
remainder += ticks % n;
mean += remainder / n;
remainder %= n;
}
return TimeSpan.FromTicks(mean);
}
TimeSpan average = mylistoftimespans.Mean();