Fernando
Fernando

Reputation: 4028

Group DateTime by an arbitrary time interval

I have an IEnumerable of an item class defined like this:

public class Item {
    public DateTime Date { get; private set; }
    public decimal? Value { get; private set; }

    public Item(DateTime date, decimal? value) {
     Date = date;
     Value = value;
    }
}

These items are in a specific time interval (5 minutes for exemple). I need to group them by the date, but changing the interval. For example, if the items are in the following order:

2010-08-24 00:05
2010-08-24 00:10
2010-08-24 00:15
2010-08-24 00:20
2010-08-24 00:25
2010-08-24 00:30

and I want to group them into a 15 minutes interval, the result should look like this:

2010-08-24 00:15
2010-08-24 00:30

The interval is provided by another class, but I can get the milliseconds that represent that interval (for example, Interval.FromMinutes(5).GetMilliseconds() should return 300000). The question is how can I write a grouping function that allows me to do something like this : data = items.GroupBy(t => GroupingFunction(t.DateTime, interval)) and obtain that result?

Update: the interval will not be necessarily in minutes. It could be in hours, minutes or even days.

Upvotes: 9

Views: 6989

Answers (3)

James Curran
James Curran

Reputation: 103485

 data = items.GroupBy(t => (int)(t.DateTime.Minutes/interval)))

Upvotes: 3

Dave Swersky
Dave Swersky

Reputation: 34810

Have you tried grouping by a modulus?

Untested stream-of-consciousness pseudocode follows:

data = items.GroupBy(t => t.TimeInterval % 15 == 0);

Upvotes: 0

driis
driis

Reputation: 164281

Something like this ?

        DateTime[] dateTimes = new[]
                                   {
                                       new DateTime(2010, 8, 24, 0, 5, 0),
                                       new DateTime(2010, 8, 24, 0, 10, 0),
                                       new DateTime(2010, 8, 24, 0, 15, 0),
                                       new DateTime(2010, 8, 24, 0, 20, 0),
                                       new DateTime(2010, 8, 24, 0, 25, 0),
                                       new DateTime(2010, 8, 24, 0, 30, 0)
                                   };
        TimeSpan interval = new TimeSpan(0, 15, 0);     // 15 minutes.

        var groupedTimes = from dt in dateTimes
                           group dt by dt.Ticks/interval.Ticks
                           into g
                           select new {Begin = new DateTime(g.Key*interval.Ticks), Values = g.ToList()};

        foreach (var value in groupedTimes)
        {
            Console.WriteLine(value.Begin);
            Console.WriteLine("\t{0}", String.Join(", ", value.Values));
        }

Upvotes: 13

Related Questions