MindGame
MindGame

Reputation: 1251

Calculate Average Age from a list of dates using linq

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

Answers (4)

D Stanley
D Stanley

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

Tommaso Belluzzo
Tommaso Belluzzo

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

NetMage
NetMage

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 TimeSpans 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

rokkerboci
rokkerboci

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

Related Questions