Reputation: 1251
I have a list of dates where I want to calculate the average age. I'm not sure what the best way of doing this using LINQ.
2017-04-13 08:31:00.000
2017-04-12 07:53:00.000
2017-04-11 07:59:00.000
2017-04-10 08:16:00.000
2017-04-09 15:11:00.000
2017-04-08 08:28:00.000
2017-04-06 08:26:00.000
Should I convert the date values to ticks and then calculate the average?
Upvotes: 0
Views: 2051
Reputation: 152501
Should I convert the date values to ticks and then calculate the average?
No need - you can subtract two DateTimes
and get a TimeSpan
that will give you the difference between them in whatever unit you want. Just get the number of days (including fractions) between now (or whatever reference date is appropriate) and each item and average them:
double avgDays = list.Average(dt => (DateTime.Now - dt).TotalDays);
Upvotes: 3
Reputation: 23675
DateTime
, internally, is represented by a specific number of ticks, that can be retrieved using the Ticks
property. Since Enumerable.Average()
does not work with DateTime
and Timestamp
types, you could proceed as follows:
List<DateTime> dates = new List<DateTime>()
{
DateTime.ParseExact("2017-04-13 08:31:00.000", "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture),
DateTime.ParseExact("2017-04-12 07:53:00.000", "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture),
DateTime.ParseExact("2017-04-11 07:59:00.000", "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture),
DateTime.ParseExact("2017-04-10 08:16:00.000", "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture),
DateTime.ParseExact("2017-04-09 15:11:00.000", "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture)
};
Int64 avgTicks = (Int64)dates.Select(d => d.Ticks).Average();
DateTime avgDate = new DateTime(avgTicks);
If by "age" you mean years and you are looking for a diff to the respect of the current year, then:
Int32 avgYear = DateTime.Now.Year - avgDate.Year;
If you want an absolute difference:
Int32 avgYear = Math.Abs(DateTime.Now.Year - avgDate.Year);
Upvotes: 0
Reputation: 26907
Using an extension method,
public static TimeSpan Average(this IEnumerable<TimeSpan> spans) => TimeSpan.FromSeconds(spans.Select(s => s.TotalSeconds).Average());
You can compute the ages as TimeSpan
s and get the average TimeSpan:
var now = DateTime.Now; // don't slide the ages by computational time
var avgAge = birthDates.Select(d => now - d).Average();
Or expand the extension method manually:
var avgAge = TimeSpan.FromSeconds(birthDates.Select(d => (now - d).TotalSeconds).Average());
Then you can use convert the avgAge
to whatever units you need:
var avgAgeInYears = (avgAge.TotalDays/365.2425);
Upvotes: -1
Reputation: 1167
You can use LINQ's Average function.
IEnumerable<DateTime> timeSpan = new List<DateTime>()
{
DateTime.Parse("2017-04-13 08:31:00.000"),
DateTime.Parse("2017-04-12 07:53:00.000"),
DateTime.Parse("2017-04-11 07:59:00.000"),
DateTime.Parse("2017-04-10 08:16:00.000"),
DateTime.Parse("2017-04-09 15:11:00.000")
};
DateTime average = new DateTime((long)timeSpan.Average(x => x.Ticks));
Upvotes: 0