2010-07-29 9 views
44

Tengo una DateTime StartDate y EndDate.iterar sobre cada día entre StartDate y EndDate

¿Cómo puedo, independientemente de los tiempos, iterar a través de cada día entre los dos?

Ejemplo: StartDate es 7/20/2010 5:10:32 PM y EndDate es 7/29/2010 1:59:12 AM.

Quiero ser capaz de recorrer a través de 7/20, 7/21, 7/22, 7/29 ...

+0

Echa un vistazo aquí: http://stackoverflow.com/questions/533767/how-do-you-iterate-through-every-day-of-the-year –

Respuesta

112
for(DateTime date = StartDate; date.Date <= EndDate.Date; date = date.AddDays(1)) 
{ 
    ... 
} 

The .Date es para asegurarse de tener ese último día, como en el ejemplo.

+0

creo que quieres 'date.Date <= EndDate.Date' lo que se obtiene el dia final. –

+2

Esto entra en un ciclo infinito, el método AddDays no cambia la fecha, pero devuelve una nueva instancia de DateTime. Uso fecha = date.AddDays (1) en su lugar. – corvuscorax

+0

@Dean: Gracias, viste tu comentario después del cambio. –

0
DateTime date = DateTime.Now; 
DateTime endDate = date.AddDays(10); 

while (date < endDate) 
{ 
    Console.WriteLine(date); 
    date = date.AddDays(1); 
} 
3

Debes tener cuidado con la fecha de finalización. Por ejemplo, en

Ejemplo: StartDate es 7/20/2010 5:10:32 PM y EndDate es 7/29/2010 1:59:12 AM.
Quiero ser capaz de recorrer a través de 7/20, 7/21, 7/22, 7/29 ...

date < endDate no incluirá 7/29 alguna vez. Cuando agrega 1 día a 7/28 5:10 PM, se convierte en 7/29 5:10 PM que es más alto que 7/29 2 AM.

Si eso no es lo que quieres, entonces yo diría que lo hace

for (DateTime date = start.Date; date <= end.Date; date += TimeSpan.FromDays(1)) 
{ 
    Console.WriteLine(date.ToString()); 
} 

o algo por el estilo.

11

Un método alternativo que podría ser más reutilizable es escribir un método de extensión en la fecha y hora y devolver un IEnumerable.

Por ejemplo, puede definir una clase:

public static class MyExtensions 
{ 
    public static IEnumerable EachDay(this DateTime start, DateTime end) 
    { 
     // Remove time info from start date (we only care about day). 
     DateTime currentDay = new DateTime(start.Year, start.Month, start.Day); 
     while (currentDay <= end) 
     { 
      yield return currentDay; 
      currentDay = currentDay.AddDays(1); 
     } 
    } 
} 

Ahora en el código de llamada se puede hacer lo siguiente:

DateTime start = DateTime.Now; 
DateTime end = start.AddDays(20); 
foreach (var day in start.EachDay(end)) 
{ 
    ... 
} 

Otra ventaja de este enfoque es que hace que sea trivial agregue EachWeek, EachMonth etc. A continuación, todos estarán accesibles en DateTime.

+1

Puede eliminar información de tiempo de la fecha con DateTime.Date: https://msdn.microsoft.com/en-us/library/system.datetime.date(v=vs.110).aspx – Oswin

+1

¿por qué no? hacerlo seguro? IEnumerable ? – duedl0r

0

Los bucles de @Yuriy Faktorovich, @healsjnr y @mho serán todos lanzar una excepción si System.ArgumentOutOfRangeException: The added or subtracted value results in an un-representable DateTime EndDate == DateTime.MaxValue. Para evitar esto, agregue un control extra al final del bucle

for(DateTime date = StartDate; date.Date <= EndDate.Date; date = date.AddDays(1)) 
{ 
    ... 
    if (date.Date == DateTime.MaxValue.Date) 
    { 
     break; 
    } 
} 

(Me habría publicado esto como un comentario a la respuesta de @Yuriy Faktorovich, pero me falta la reputación)

Cuestiones relacionadas