49

I have a DateTime StartDate and EndDate.

How can I, irrespective of times, iterate across each Day between those two?

Example: StartDate is 7/20/2010 5:10:32 PM and EndDate is 7/29/2010 1:59:12 AM.

I want to be able to iterate across 7/20, 7/21, 7/22 .. 7/29.

Ondrej Janacek
  • 12,486
  • 14
  • 59
  • 93
Alex
  • 75,813
  • 86
  • 255
  • 348

5 Answers5

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

The .Date is to make sure you have that last day, like in the example.

Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
14

An alternative method that might be more reusable is to write an extension method on DateTime and return an IEnumerable.

For example, you can define a class:

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

Now in the calling code you can do the following:

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

Another advantage to this approach is that it makes it trivial to add EachWeek, EachMonth etc. These will then all be accessible on DateTime.

healsjnr
  • 405
  • 3
  • 10
  • 1
    You can remove time info from the date with DateTime.Date : https://msdn.microsoft.com/en-us/library/system.datetime.date(v=vs.110).aspx – Oswin Aug 18 '16 at 13:58
  • 1
    why don't you do it type-safe? IEnumerable? – duedl0r Jan 12 '18 at 00:00
4

You have to be careful about end-date. For example, in

Example: StartDate is 7/20/2010 5:10:32 PM and EndDate is 7/29/2010 1:59:12 AM.
I want to be able to iterate across 7/20, 7/21, 7/22 .. 7/29.

date < endDate will not include 7/29 ever. When you add 1 day to 7/28 5:10 PM - it becomes 7/29 5:10 PM which is higher than 7/29 2 AM.

If that is not what you want then I'd say you do

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

or something to that effect.

haraman
  • 2,744
  • 2
  • 27
  • 50
Om Deshmane
  • 808
  • 6
  • 11
3

The loops of @Yuriy Faktorovich, @healsjnr and @mho will all throw a System.ArgumentOutOfRangeException: The added or subtracted value results in an un-representable DateTime exception if EndDate == DateTime.MaxValue. To prevent this, add an extra check at the end of the loop

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

(I would have posted this as a comment to @Yuriy Faktorovich's answer, but I lack reputation)

Henk Kok
  • 353
  • 6
  • 10
0
DateTime date = DateTime.Now;
DateTime endDate = date.AddDays(10);

while (date < endDate)
{
  Console.WriteLine(date);
  date = date.AddDays(1);
}
benPearce
  • 37,735
  • 14
  • 62
  • 96