Create array of months between two dates
Solution 1
Try this:
static IEnumerable<DateTime> monthsBetween(DateTime d0, DateTime d1)
{
return Enumerable.Range(0, (d1.Year - d0.Year) * 12 + (d1.Month - d0.Month + 1))
.Select(m => new DateTime(d0.Year, d0.Month, 1).AddMonths(m));
}
This includes both the starting month and the ending month. This finds how many months there is, and then creates a new DateTime
based on d0
´s year and month. That means the months are like yyyy-MM-01
. If you want it to includes the time and day of d0
you can replace new DateTime(d0.Year, d0.Month, 1).AddMonths(m)
by d0.AddMonths(m)
.
I see you need an array, in that case you just use monthsBetween(..., ...).ToArray()
or put .ToArray()
inside the method.
Solution 2
Since I just needed the year and month in between two dates I modified Lasse Espeholt answer a little. suppose: d0 = 2012-11-03
d1 = 2013-02-05
The result will be something like this:
2012-11
2012-12
2013-01
2013-02
private List<Tuple<int,int>> year_month_Between(DateTime d0, DateTime d1)
{
List<DateTime> datemonth= Enumerable.Range(0, (d1.Year - d0.Year) * 12 + (d1.Month - d0.Month + 1))
.Select(m => new DateTime(d0.Year, d0.Month, 1).AddMonths(m)).ToList();
List<Tuple<int, int>> yearmonth= new List<Tuple<int,int>>();
foreach (DateTime x in datemonth)
{
yearmonth.Add(new Tuple<int, int>(x.Year, x.Month));
}
return yearmonth;
}
Solution 3
Is this what you are looking for? The requirement is very ambiguous.
DateTime[] calendarMonthBoundaries = Enumerable.Range(0, 1 + endDate.Subtract(startDate).Days)
.Select(offset => startDate.AddDays(offset))
.Where(date => date.Day == 1)
.ToArray();
Solution 4
You could enumerate increments of months with:
private static IEnumerable<DateTime> ByMonths(DateTime startDate, DateTime endDate)
{
DateTime cur = startDate;
for(int i = 0; cur <= endDate; cur = startDate.AddMonths(++i))
{
yield return cur;
}
}
and then call ToArray()
on that if you want an array. It's reasonably good about having values that are likely to be what is wanted; e.g. if you start at Jan 31st you'll next get Feb 28th (or 29th on leap years), then Mar 31st, then Apr 30th and so on.
Comments
-
Andy Evans almost 2 years
I have the following snippet that I use to get the individual dates between two dates:
DateTime[] output = Enumerable.Range(0, 1 + endDate.Subtract(startDate).Days) .Select(offset => startDate.AddDays(offset)) .ToArray();
However, the following section
endDate.Subtract(startDate).Days
does not have a .Months to return the months in the date range.
For example, if I provide 1/1/2010 and 6/1/2010 I would expect to return 1/1/2010, 2/1/2010, 3/1/2010, 4/1/2010, 5/1/2010 and 6/1/2010.
Any ideas?
-
Dave Lucre about 11 yearsDateTime[] months = ByMonths({30/01/2013 12:00:00 AM}, {4/04/2013 12:00:00 AM}).ToArray(); This only returns 3 months (jan, feb, mar), April is missing.
-
Jon Hanna almost 11 years@DaveLucre I'm not sure that's a bad thing, because I'm not sure just what the requirement in the question is considering "between". It could certainly be amended to include April in that case, I just don't know if it should.
-
Rudean over 2 yearsI actually like how simple this solution is! Just analyze all dates between start date and end date, but return only start month dates. Probably not the quickest solution but pretty straightforward.
-
Rudean over 2 yearsAnd if you want to get not months, but years, you can do it like this Enumerable.Range(0, (d1.Year - d0.Year) + 1) .Select(m => new DateTime(d0.Year, 1, 1).AddYears(m))