4

I want to get all the months with year in format MM/YYYY between two given dates.

Something like this:

Start date: 08/1/2012
End date: 03/1/2013

Result:

09/2012
10/2012
11/2012
12/2012
01/2013
02/2013
03/2013

This is the code I have but it doesn't work as I want.

for (int i = StartDate.Year; i <= EndDate.Year; i++)
{
  for (int j = StartDate.Month+1; j <= 12 ; j++)
  {
    Console.WriteLine(j.ToString("00") + "/" + i.ToString()));
  } 
}

Thank you in advance for your help.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Yatiac
  • 1,820
  • 3
  • 15
  • 25
  • Lookie here: http://stackoverflow.com/questions/11930565/list-the-months-between-two-dates – EagleBeak Oct 04 '13 at 12:33
  • Any answer below will produce the correct output, but you will not have really learned anything. For a start, think about this: your piece of code does not depend on EndDate.Month. This cannot be correct, right? – Anton Tykhyy Oct 04 '13 at 14:38

6 Answers6

4
for 
(
    DateTime date = new DateTime(2012, 08, 01).AddMonths(1);
    date <= new DateTime(2013, 03, 01);
    date = date.AddMonths(1)
)
{
    Console.WriteLine(date.ToString("MM/yyyy"));
}

This would be more readable and robust if you write a separate enumerator for the dates, like so:

public static IEnumerable<DateTime> MonthsBetween(int startMonth, int startYear, int endMonth, int endYear)
{
    for
    (
        DateTime date = new DateTime(startYear, startMonth, 01).AddMonths(1);
        date <= new DateTime(endYear, endMonth, 01);
        date = date.AddMonths(1)
    )
    {
        yield return date;
    }
}

Which you could call like so:

foreach (var date in MonthsBetween(08, 2012, 03, 2013))
{
    Console.WriteLine(date.ToString("MM/yyyy"));
}

Note that this range excludes the first month, which from your example it seems you want.

If you don't want to skip the first month, remove the .AddMonths(1) from the line creating the start date.

(Personally, I'd prefer to include the starting month in the output, but that is not what you asked for.)

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • 1
    Fails to account for the last month if the day in enddate is one day or more less than the day in startdate (try to use month=1 and day=8 and the same for the enddate) – Steve Oct 04 '13 at 12:39
  • @steve I'm assuming that day will always be specified as 1 because we're only interested in months, not days (according to OP question specifying output as MM/yyyy). To make this clear, I'll add a method to enumerate the months. – Matthew Watson Oct 04 '13 at 12:47
  • 1
    Perhaps, not sure, but if you ask _all the months_ between two dates I could also assume an inclusive statement and saying _From 8 January 2012 to 3 January 2013_ I would include also January 2013. But this should be clarified by the OP – Steve Oct 04 '13 at 12:51
  • @steve Oh sorry, misunderstood what you're saying. Will fix! – Matthew Watson Oct 04 '13 at 13:01
1

You can for loop with increasing month values with DateTime.AddMonths method like;

DateTime dt1 = new DateTime(2012, 08, 01);
DateTime dt2 = new DateTime(2013, 03, 01);
DateTime dt3 = new DateTime();
for (dt3 = dt1.AddMonths(1); dt3 <= dt2; dt3 = dt3.AddMonths(1))
{
    Console.WriteLine(dt3.ToString("MM/yyyy"));
}

Output will be;

09.2012
10.2012
11.2012
12.2012
01.2013
02.2013
03.2013

Here a DEMO.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
1

There is the possibility that the day value of your startdate is greater than the day value of the enddate. In this case it is necessary to normalize the enddate to the end of the month

List<string> result = new List<string>();
DateTime startDate = new DateTime(2012, 1, 8);
DateTime endDate = new DateTime(2013, 1, 3);
DateTime temp = startDate;
endDate = new DateTime (endDate.Year, endDate.Month, DateTime.DaysInMonth(endDate.Year,endDate.Month));
while (temp <= endDate)
{
    Console.WriteLine((string.Format("{0}/{1}", temp.Month, temp.Year));
    temp = temp.AddMonth(1);
}
Steve
  • 213,761
  • 22
  • 232
  • 286
0

You can use this code, its more elegant:

for (DateTime date = StartDate; date <= EndDate; date = date.AddMonths(1))
    Console.WriteLine(date.ToString("MM/yyyy"));
hmnzr
  • 1,390
  • 1
  • 15
  • 24
0

Not tested but how about something like this:

public IEnumerable<String> EachMonth(DateTime start, DateTime end)
{
    for(var m = start.Date; m.Date <= end.Date; m = m.AddMonths(1))
        yield return m.ToString("MM/YYYY");
}

And then you could use it like this:

foreach (String month in EachMonth(StartDate, EndDate))
Dave Sexton
  • 10,768
  • 3
  • 42
  • 56
0
DateTime StartDate = Convert.ToDateTime("08/1/2012");
        DateTime EndDate = Convert.ToDateTime("03/1/2013");

        for (DateTime i = StartDate; i <= EndDate; i = i.AddMonths(1))
        {
            Response.Write(i.ToString("MM") + "/" + i.ToString("yyyy")+"<br />");
        }
user2846553
  • 187
  • 1
  • 5