How to find an average date/time in the array of DateTime values
The code:
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);
is Wrong. Average=(x1 + x2 + ... xN) / N not (x1/N + x2/N + ... xN/N)
Try:
var avg=new DateTime((long)dates.Select(d => d.Ticks).Average());
Source: Taken from Here and modified a bit.
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
Then you can do:
var averageDateTime = DateTime
.MinValue
.AddSeconds
((dates
.Sum(r => (r - DateTime.MinValue).TotalSeconds))
/ dates.Count);
Console.WriteLine(averageDateTime.ToString("yyyy-MMM-dd HH:mm:ss"));
Output in: 1956-Dec-29 06:09:25
Originally the code from the article was like:
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);
If you have large list you can use below method
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);
This shouldn't overflow, it does assume the datetimes are ordered though:
var first = dates.First().Ticks;
var average = new DateTime(first + (long) dates.Average(d => d.Ticks - first));
The above does in fact overflow with larger lists and larger gaps. I think you could use seconds for better range. (again, sorted first) Also, this might not be the most performant method, but still completed with 10M dates relatively quickly for me. Not sure if it's easier to read or not, YYMV.
var first = dates.First();
var average = first.AddSeconds(dates.Average(d => (d - first).TotalSeconds));