Ответ 1
Если у вас есть большой список, вы можете использовать ниже метод
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);
Если у меня есть массив значений DateTime:
List<DateTime> 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);
Это не должно переполняться, но предполагается, что datetimes заказаны:
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));
class Program
{
static void Main(string[] args)
{
List<DateTime> dates = new List<DateTime>(){
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<long> longs)
{
long count = longs.Count();
long mean = 0;
foreach (var val in longs)
{
mean += val / count;
}
return mean;
}
public static DateTime Average(this IEnumerable<DateTime> dates)
{
return new DateTime(dates.Select(x => x.Ticks).Average());
}
}
Источник: взято из здесь и немного изменилось.
List<DateTime> dates = new List<DateTime>();
//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);
Код:
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);
Неверно. Average = (x1 + x2 +... xN)/N not (x1/N + x2/N +... xN/N)
Try:
var avg=new DateTime((long)dates.Select(d => d.Ticks).Average());