如何在DateTime值数组中查找平均日期/时间

如果我有一个DateTime值数组:

List arrayDateTimes; 

在它们中找到平均DateTime的方法是什么?

例如,如果我有:

 2003-May-21 15:00:00 2003-May-21 19:00:00 2003-May-21 20:00:00 

平均值应该是:

 2003-May-21 18:00:00 

如果您有大型列表,可以使用以下方法

 var count = dates.Count; double temp = 0D; for (int i = 0; i < count; i++) { temp += dates[i].Ticks / (double)count; } var average = new DateTime((long)temp); 

这不应该溢出,它确实假设日期时间是有序的,但:

 var first = dates.First().Ticks; var average = new DateTime(first + (long) dates.Average(d => d.Ticks - first)); 

实际上,上面确实溢出了更大的列表和更大的间隙。 我认为你可以用秒来获得更好的射程 。 (再次,排序第一)此外,这可能不是最高性能的方法,但仍然完成10M日期对我来说相对较快。 不确定是否更容易阅读,YYMV。

 var first = dates.First(); var average = first.AddSeconds(dates.Average(d => (d - first).TotalSeconds)); 

代码:

 var count = dates.Count; double temp = 0D; for (int i = 0; i < count; i++) { temp += dates[i].Ticks / (double)count; } var average = new DateTime((long)temp); 

是错的。 平均值=(x1 + x2 + ... xN)/ N不是(x1 / N + x2 / N + ... xN / N)

尝试:

 var avg=new DateTime((long)dates.Select(d => d.Ticks).Average()); 
 class Program { static void Main(string[] args) { List dates = new List(){ new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 17, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 17, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 17, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), new DateTime(2003, 5, 21, 18, 0, 0), new DateTime(2003, 5, 21, 19, 0, 0), new DateTime(2003, 5, 21, 20, 0, 0), new DateTime(2003, 5, 21, 16, 0, 0), }; var averageDate = dates.Average(); Console.WriteLine(averageDate); Console.ReadKey(); } } public static class Extensions { public static long Average(this IEnumerable longs) { long count = longs.Count(); long mean = 0; foreach (var val in longs) { mean += val / count; } return mean; } public static DateTime Average(this IEnumerable dates) { return new DateTime(dates.Select(x => x.Ticks).Average()); } } 

来源:取自Here并修改了一下。

 List dates = new List(); //Add dates for (int i = 1; i <= 28; i++) //days for (int j = 1; j <= 12; j++) //month for (int k = 1900; k <= 2013; k++) //year dates.Add(new DateTime(k, j, i, 1, 2, 3)); //over 38000 dates 

然后你可以这样做:

 var averageDateTime = DateTime .MinValue .AddSeconds ((dates .Sum(r => (r - DateTime.MinValue).TotalSeconds)) / dates.Count); Console.WriteLine(averageDateTime.ToString("yyyy-MMM-dd HH:mm:ss")); 

输出: 1956-Dec-29 06:09:25

最初文章中的代码如下:

 double totalSec = 0; for (int i = 0; i < dates.Count; i++) { TimeSpan ts = dates[i].Subtract(DateTime.MinValue); totalSec += ts.TotalSeconds; } double averageSec = totalSec / dates.Count; DateTime averageDateTime = DateTime.MinValue.AddSeconds(averageSec); 

neouser99的答案是正确的。 它通过增加平均值来防止溢出。

然而, DavidJiménez的这个答案是错误的,因为它没有处理溢出和他对公式的误解。

平均值=(x1 + x2 + … xN)/ N不是(x1 / N + x2 / N + … xN / N)

这些是相同的公式。 这是使用分配属性的简单数学:

 2(x + y) = 2x + 2y 

平均公式与您的总和乘以1 / N相同。 或者将每个X乘以1 / N并将它们相加。

 1/n (x1 + x2 + ... xn) 

由分配财产变成:

 x1/n + x2/n + ... xn/n 

以下是有关分配属性的一些信息

他的答案也很糟糕,因为它不会像接受的答案那样阻止溢出。

我会评论他的答复,但我没有足够的声誉。