4

If I have a pair of dates, and I want to generate a list of all the dates between them (inclusive), I can do something like:

System.DateTime s = new System.DateTime(2010, 06, 05);
System.DateTime e = new System.DateTime(2010, 06, 09);
var list = Enumerable.Range(0, (e - s).Days)
    .Select(value => s.AddDays(value));

What I'm stuck on is that I've got a list of pairs of dates that I want to explode into a list of all the dates between them. Example:

{2010-05-06, 2010-05-09}, {2010-05-12, 2010-05-15}

should result in

{2010-05-06, 2010-05-07, 2010-05-08, 2010-05-09, 2010-05-12, 2010-05-13, 2010-05-14, 2010-05-15}

Note the pairs of dates are guaranteed not to overlap each other.

Robert Gowland
  • 7,677
  • 6
  • 40
  • 58
  • 2
    TimeSpan.Days **!=** TimeSpan.TotalDays http://msdn.microsoft.com/en-us/library/system.timespan.days(v=VS.100).aspx http://msdn.microsoft.com/en-us/library/system.timespan.totaldays(v=VS.100).aspx – dtb Apr 16 '10 at 17:58
  • Yes, Days != TotalDays, however Days is what I want here. See the examples from the links you gave: TimeSpan( 1 ).Days == 0; TimeSpan( 1 ).TotalDays == 1.15740740740741E-12; TimeSpan( 111222333444555 ).Days == 128; TimeSpan( 111222333444555 ).TotalDays == 128.729552597865; In the first example, looping 0..0 would give a single day, which is what I want. In the second example, looping 0..128 would give 129 days, which again, is what I want. I suppose I could loop over 1..ceil(128.729552597865) and then return s.AddDays(value - 1), but why would I? – Robert Gowland Apr 16 '10 at 19:24
  • Just pointing out that using `Days` breaks when the two `DateTime` values are more than a month apart from each other. :) – dtb Apr 16 '10 at 20:34

2 Answers2

6
var result = listOfPairs.SelectMany(pair =>
                 Enumerable.Range(0, (pair.Item2 - pair.Item1).TotalDays)
                           .Select(days => pair.Item1.AddDays(days)));
dtb
  • 213,145
  • 36
  • 401
  • 431
  • Yes, this is what I was looking for: a LINQy extensible method of doing. Awesome, thanks. – Robert Gowland Apr 16 '10 at 19:41
  • 2
    This was useful to me. I needed to explode only a single date range, and this is what I used: `Enumerable.Range(0, (int)(endDate - startDate).TotalDays).Select(days => startDate.AddDays(days));`. Note that I had to add 1 day to EndDate to make sure the last day was in there. – Christopher Dec 10 '12 at 22:40
0

I think you could use a simple List<DateTime> to accomplish what you want.

List<DateTime> list = new List<DateTime>();
list.AddRange(GetListDates(d1, d2));
list.AddRange(GetListDates(d3, d4));
Paulo Santos
  • 11,285
  • 4
  • 39
  • 65