2010-08-24 15 views
7

tengo una IEnumerable de una clase de elemento definido como esto:Grupo DateTime por un tiempo arbitrario intervalo

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; 
    } 
} 

Estos artículos están en un intervalo de tiempo específico (5 minutos para exemple). Necesito agruparlos por la fecha, pero cambiando el intervalo. Por ejemplo, si los artículos están en el siguiente orden:

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 

y quiero agruparlos en un intervalo de 15 minutos, el resultado debe ser similar a esto:

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

El intervalo es proporcionada por otra clase, pero puedo obtener los milisegundos que representan ese intervalo (por ejemplo, Interval.FromMinutes (5) .GetMilliseconds() debería devolver 300000). La pregunta es ¿cómo puedo escribir una función de agrupación que me permita hacer algo como esto: data = items.GroupBy(t => GroupingFunction(t.DateTime, interval)) y obtener ese resultado?

Actualización: el intervalo no será necesariamente en minutos. Podría ser en horas, minutos o incluso días.

+0

¿Quieres agrupación o filtrado (como en el ejemplo)? –

+0

Agrupación. En el ejemplo 00:05, 00:10 y 00:15 se convirtió en 00:15 (voy a sumar los valores de los tres elementos y mantener la marca de hora 00:15). – Fernando

Respuesta

7

¿Algo como esto?

 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)); 
     } 
0

¿Ha intentado agrupar por módulo?

No comprobado pseudocódigo la corriente de la conciencia sigue:

data = items.GroupBy(t => t.TimeInterval % 15 == 0); 
1
data = items.GroupBy(t => (int)(t.DateTime.Minutes/interval))) 
+0

Esto solo funcionará siempre que el intervalo sea inferior a 60 minutos. – driis

Cuestiones relacionadas