23

I have been trying to write this loop and it just keeps getting more complicated. Basically I want to take a given date and loop through every month until I reach the current month. So if the start date is 11/1/2011 then I want to loop through

11/2011, 12/2011, 1/2012, 2/2012, etc.

Here is what I started with but this does not work. Once I hit a new year I need the inner loop to start over with 1 not startdate.Month. Is there a better way in general to loop through months and years? Thanks

        for (var y = startdate.Year; y <= DateTime.Now.Year; y++)
        {
            for (var m = startdate.Month; m <= 12; m++)
            {
                  //do something with m and y
            }
        }
Rochelle C
  • 928
  • 3
  • 10
  • 22

6 Answers6

38
Date target = new Date(2011, 4, 1);
while (target < Date.Today) {
  // do something with target.Month and target.Year
  target = target.AddMonths(1);
}
Sam Axe
  • 33,313
  • 9
  • 55
  • 89
  • 2
    Just be aware that you might get inconsistent results with this depending on how you handle the 'day' components. If today's date is 2013-11-10, and target date is 2013-10-01, then your loop hits 2013-10 and 2013-11. But if the target date is 2013-10-20, then your loop only hits 2013-10 (it wont hit the current month). – thecodefish Nov 07 '13 at 03:32
  • 1
    Absolutely. But that is outside the scope of the question :) Good to be aware of though. – Sam Axe Nov 07 '13 at 03:37
  • 2
    @thecodefish - from the question, I was assuming that the day would always be passed in as a 1, so I think Dan-o's code is fine. But I agree that you would need to check or enforce that. – Matt Johnson-Pint Nov 07 '13 at 03:59
  • 2
    I think this will give me a good start. I wanted to eliminate the day portion for exactly the reason thecodefish pointed out. So I would have to set the startdate.day = 1, today's date.day = 1, then have while(startdate <= today's date) and I could be sure the current month always gets hit. – Rochelle C Nov 07 '13 at 13:49
  • This answer is incorrect -- see mine below for some fixes. – Slothario Jun 26 '18 at 14:12
13
DateTime endDate = DateTime.Today;
for (DateTime dt = startDate; dt <= endDate; dt = dt.AddMonths(1))
{
    Console.WriteLine("{0:M/yyyy}", dt);
}

But if you prefer while loops, then vote for Dan-o. I did. :)

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
5

Sam's answer is nice but ultimately incorrect (if your start day is 20 and your end day is 10, it won't include the last month). Here's a version that works:

    public void GetMonths(DateTime startTime, DateTime endTime)
    {
        var dateCounter = new DateTime(startTime.Year, startTime.Month, 1);
        var endDateTarget = new DateTime(endTime.Year, endTime.Month, 1);

        while (dateCounter <= endDateTarget)
        {
            Console.WriteLine($"The year and month is: {dateCounter.Year}, {dateCounter.Month}");
            dateCounter = dateCounter.AddMonths(1);
        }
    }
Slothario
  • 2,830
  • 3
  • 31
  • 47
2

This will loop over the months and the day of the month will not be a problem.

var date = startDate;
var endDate = DateTime.Now;

while(date.Year < endDate.Year || (date.Year == endDate.Year && date.Month <= endDate.Month))
{
    Console.WriteLine($"{date.Month}/{date.Year}");
    date = date.AddMonths(1);
}
Huseyin Yagli
  • 9,896
  • 6
  • 41
  • 50
1

Generate a range (as IEnumerable`DateTime) of first days of a month in between of a given dates:

from range in new[] {
    new {
        start = new DateTime(2017, 6, 23),
        end = new DateTime(2018, 09, 11)
    }
}
select (
    from y in Enumerable.Range(
        range.start.Year, range.end.Year - 
        range.start.Year + 1
    )
    let ms = y == range.start.Year ? range.start.Month : 1
    let me = y == range.end.Year ? range.end.Month : 12
    select 
        from m in Enumerable.Range(ms, me - ms + 1)
        select new DateTime(y, m, 1)
).SelectMany(y => y)
esteewhy
  • 1,300
  • 13
  • 23
0
while (startDate <= DateTime.Now)
            {
                //here you will get every new month in  year
                Console.WriteLine(startDate.Month);
                //Add Month
                startDate=startDate.AddMonths(1);
            }
Sudhakar Tillapudi
  • 25,935
  • 5
  • 37
  • 67