2010-09-17 26 views
100

Estoy generando gráficos de varias series con la fecha a lo largo del eje X.Crear una matriz o lista de todas las fechas entre dos fechas

El problema es que no todas las series en el gráfico tienen las mismas fechas en el rango de fechas. Lo que significa que si elijo desde el 1 de febrero hasta el 30 de abril, una serie puede tener datos que comienzan el 1 de febrero pero solo se extienden hasta fines de marzo, pero otra serie puede tener datos para todo el rango de fechas.

Esto sesga los cuadros que necesito crear. Vaya, dado el rango de fechas tomado al comienzo de la consulta, me gustaría generar una lista de fechas y completar los datos que se van a graficar, rellenando esas series con 0 para aquellas fechas que no tienen datos.

+0

¿Cómo se representan las series de tiempo? – rpax

Respuesta

221

LINQ:

Enumerable.Range(0, 1 + end.Subtract(start).Days) 
      .Select(offset => start.AddDays(offset)) 
      .ToArray(); 

bucle For:

var dates = new List<DateTime>(); 

for (var dt = start; dt <= end; dt = dt.AddDays(1)) 
{ 
    dates.Add(dt); 
} 

EDIT: En cuanto a los valores de relleno con valores por defecto en una serie de tiempo, usted podría enumerar todas las fechas en el rango de fechas completo, y elija el valor para una fecha directamente de la serie si existe, o el valor predeterminado de lo contrario. Por ejemplo:

var paddedSeries = fullDates.ToDictionary(date => date, date => timeSeries.ContainsDate(date) 
               ? timeSeries[date] : defaultValue); 
+0

Sigo el ejemplo LINQ hasta la declaración 'Seleccionar'. ¿Qué está pasando exactamente allí? – Cody

+6

Si desea un rango que dure 5 días, por ejemplo 4/9 - 4/13, la llamada a Enumerable.Range crearía una colección {0,1,2,3,4}. La instrucción select toma esa colección y para cada elemento, agrega ese valor a la fecha de inicio y devuelve la nueva fecha. # 4/9/2012 # .AddDays (0) = 4/9/2012, # 4/9/2012 # .AddDays (1) = 4/10/2012, # 4/9/2012 # .AddDays (2) = 4/11/2012, y así sucesivamente, generando así el rango de fechas. –

+6

Probablemente deberías usar 'TotalDays' y no' Days' – yellowblood

28
public static IEnumerable<DateTime> GetDateRange(DateTime startDate, DateTime endDate) 
{ 
    if (endDate < startDate) 
     throw new ArgumentException("endDate must be greater than or equal to startDate"); 

    while (startDate <= endDate) 
    { 
     yield return startDate; 
     startDate = startDate.AddDays(1); 
    } 
} 
+0

Si desea comparar solo la parte de Fecha, modifique la condición while : while (startDate.Date <= endDate.Date). De lo contrario, obtendrá un rango diferente según cómo se construya el valor DateTime. –

+0

Dado que el ciclo debe finalizar cuando es igual a la fecha de finalización porque necesitamos fechas entre dos inicio y finalización, por lo que la fecha de finalización no debe incluir, pero la condición <= también devuelve enddate. –

1

Nuestro maestro residente Jon Skeet tiene una gran Range Class que pueden hacer esto para DateTime y otros tipos.

19

Sé que esto es una entrada antigua, pero trate de usar un método de extensión:

public static IEnumerable<DateTime> Range(this DateTime startDate, DateTime endDate) 
    { 
     return Enumerable.Range(0, (endDate - startDate).Days + 1).Select(d => startDate.AddDays(d)); 
    } 

y utilizar de esta manera

var dates = new DateTime(2000, 1, 1).Range(new DateTime(2000, 1, 31)); 

Siéntase libre de elegir sus propias fechas, que no tiene restringirse a enero de 2000.

+0

Ah, me encantan los métodos de extensión. – Gustav

2
list = list.Where(s => s.startDate >= Input_startDate && s.endDate <= Input_endDate); 

 

Cuestiones relacionadas