tags:

views:

58

answers:

3

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.

+3  A: 

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));
        }
driis
+1  A: 

Have you tried grouping by a modulus?

Untested stream-of-consciousness pseudocode follows:

data = items.GroupBy(t => t.TimeInterval % 15 == 0);
Dave Swersky
A: 
 data = items.GroupBy(t => (int)(t.DateTime.Minutes/interval)))
James Curran
This will only work as long as interval is less than 60 minutes.
driis