title: Get a list of date Ranges from a list Of dates
body: <p>I am looking to get a list of date ranges (with Days) from a list of dates. </p>
  
  <p>There may or may not be consecutive dates but there may be consistent gaps in the week range (i.e. All Mondays, Wednesdays and Thursdays OR ALL Mondays and Sundays, it can be any combination from 1 to 7 days of the week)</p>
  
  <p>Example 1 - List of dates spanning 2 months that all fall on a Monday, Wednesday or Friday</p>
  
  <pre><code>ID  Date        Day
  31  2016-02-01  Monday
  31  2016-02-03  Wednesday
  31  2016-02-05  Friday
  31  2016-02-08  Monday
  31  2016-02-10  Wednesday
  31  2016-02-12  Friday
  31  2016-02-15  Monday
  31  2016-02-17  Wednesday
  31  2016-02-19  Friday
  31  2016-02-22  Monday
  31  2016-02-24  Wednesday
  31  2016-02-26  Friday
  31  2016-02-29  Monday
  31  2016-03-02  Wednesday
  31  2016-03-04  Friday
  31  2016-03-07  Monday
  31  2016-03-09  Wednesday
  31  2016-03-11  Friday
  </code></pre>
  
  <p>Goal - Identify that all dates follow a pattern - all dates fall on same days with no gaps</p>
  
  <p>Desired output</p>
  
  <pre><code>ID                       31 
  FROMDATE                 01/02/2016
  TODATE                   11/03/2016
  OPERATINGDAY_MONDAY      TRUE
  OPERATINGDAY_TUESDAY     FALSE
  OPERATINGDAY_WEDNESDAY   TRUE
  OPERATINGDAY_THURSDAY    FALSE
  OPERATINGDAY_FRIDAY      TRUE
  OPERATINGDAY_SATURDAY    FALSE
  OPERATINGDAY_SUNDAY      FALSE
  </code></pre>
  
  <p>Example 2 - Same as above but a gap in the middle (no Friday 19th) - split into 2 date ranges </p>
  
  <pre><code>ID  Date        Day
  31  2016-02-01  Monday
  31  2016-02-03  Wednesday
  31  2016-02-05  Friday
  31  2016-02-08  Monday
  31  2016-02-10  Wednesday
  31  2016-02-12  Friday
  31  2016-02-15  Monday
  31  2016-02-17  Wednesday
  31  2016-02-22  Monday
  31  2016-02-24  Wednesday
  31  2016-02-26  Friday
  31  2016-02-29  Monday
  31  2016-03-02  Wednesday
  31  2016-03-04  Friday
  31  2016-03-07  Monday
  31  2016-03-09  Wednesday
  31  2016-03-11  Friday
  </code></pre>
  
  <p>Desired output is an object like this</p>
  
  <pre><code>ID                       31 
  FROMDATE                 01/02/2016
  TODATE                   17/02/2016
  OPERATINGDAY_MONDAY      TRUE
  OPERATINGDAY_TUESDAY     FALSE
  OPERATINGDAY_WEDNESDAY   TRUE
  OPERATINGDAY_THURSDAY    FALSE
  OPERATINGDAY_FRIDAY      TRUE
  OPERATINGDAY_SATURDAY    FALSE
  OPERATINGDAY_SUNDAY      FALSE
  
  ID                       31 
  FROMDATE                 22/02/2016
  TODATE                   11/03/2016
  OPERATINGDAY_MONDAY      TRUE
  OPERATINGDAY_TUESDAY     FALSE
  OPERATINGDAY_WEDNESDAY   TRUE
  OPERATINGDAY_THURSDAY    FALSE
  OPERATINGDAY_FRIDAY      TRUE
  OPERATINGDAY_SATURDAY    FALSE
  OPERATINGDAY_SUNDAY      FALSE
  </code></pre>
  
  <p>Example 3 - Same as example 1 but a new date date/day in the middle (Tuesday 16th)</p>
  
  <pre><code>ID  Date        Day
  31  2016-02-01  Monday
  31  2016-02-03  Wednesday
  31  2016-02-05  Friday
  31  2016-02-08  Monday
  31  2016-02-10  Wednesday
  31  2016-02-12  Friday
  31  2016-02-15  Monday
  31  2016-02-16  Tuesday
  31  2016-02-17  Wednesday
  31  2016-02-22  Monday
  31  2016-02-24  Wednesday
  31  2016-02-26  Friday
  31  2016-02-29  Monday
  31  2016-03-02  Wednesday
  31  2016-03-04  Friday
  31  2016-03-07  Monday
  31  2016-03-09  Wednesday
  31  2016-03-11  Friday
  </code></pre>
  
  <p>Desired output is an object like this</p>
  
  <pre><code>ID                       31 
  FROMDATE                 01/02/2016
  TODATE                   15/02/2016
  OPERATINGDAY_MONDAY      TRUE
  OPERATINGDAY_TUESDAY     FALSE
  OPERATINGDAY_WEDNESDAY   TRUE
  OPERATINGDAY_THURSDAY    FALSE
  OPERATINGDAY_FRIDAY      TRUE
  OPERATINGDAY_SATURDAY    FALSE
  OPERATINGDAY_SUNDAY      FALSE
  
  ID                       31 
  FROMDATE                 16/02/2016
  TODATE                   16/02/2016
  OPERATINGDAY_MONDAY      FALSE
  OPERATINGDAY_TUESDAY     TRUE
  OPERATINGDAY_WEDNESDAY   FALSE
  OPERATINGDAY_THURSDAY    FALSE
  OPERATINGDAY_FRIDAY      FALSE
  OPERATINGDAY_SATURDAY    FALSE
  OPERATINGDAY_SUNDAY      FALSE
  
  ID                       31 
  FROMDATE                 17/02/2016
  TODATE                   11/03/2016
  OPERATINGDAY_MONDAY      TRUE
  OPERATINGDAY_TUESDAY     FALSE
  OPERATINGDAY_WEDNESDAY   TRUE
  OPERATINGDAY_THURSDAY    FALSE
  OPERATINGDAY_FRIDAY      TRUE
  OPERATINGDAY_SATURDAY    FALSE
  OPERATINGDAY_SUNDAY      FALSE
  </code></pre>
  
  <p>A point in the right direction of how to attack this would be great. Preferably linq.</p>
  
  <p>The end goal is to display the data in a coherent way</p>
  
  <p><strong>Update</strong>: Here is my code that I am currently using. I am handling consecutive days and non consecutive days but I am not sure where to even start with dates that follow a certain pattern. No doubt I am handling consecutive days all wrong.</p>
  
  <pre><code>foreach (var o in option.OptionPrices)
                  {
                      var dateList = o.Dates.Select(d =&gt; d.Date).OrderBy(d =&gt; d.Date);
                      maxDate = (from d in dateList select d.Date).Max();
                      minDate = (from d in dateList select d.Date).Min();
  
                      if ((maxDate - minDate).Days + 1 == dateList.Count()) // runs everyday specified.
                      {
                          dateRange.Start = minDate;
                          dateRange.End = maxDate;
                          dateRange.OptionPriceid = o.OptionPriceId;
                          dateRange.OptionPriceName = o.Name;                        
                          dateRange.DayNames.Add("Monday");
                          dateRange.DayNames.Add("Tuesday");
                          dateRange.DayNames.Add("Wednesday");
                          dateRange.DayNames.Add("Thursday");
                          dateRange.DayNames.Add("Friday");
                          dateRange.DayNames.Add("Saturday");
                          dateRange.DayNames.Add("Sunday");
  
                          Pricing pricing = new Pricing
                          {
                              OptionId = option.OptionId,
                              OptionName = option.Name,
                              OptionPriceName = dateRange.OptionPriceName,
                              Fromdate = dateRange.Start.ToShortDateString(),
                              Todate = dateRange.End.ToShortDateString(),
                              AdultPrice = o.AdultPrice,
                              ChildPrice = o.ChildPrice,
                              InfantPrice = o.InfantPrice,
                              Operatingday_Monday = dateRange.DayNames.Contains("Monday") ? "x" : "-",
                              Operatingday_Tuesday = dateRange.DayNames.Contains("Tuesday") ? "x" : "-",
                              Operatingday_Wednesday = dateRange.DayNames.Contains("Wednesday") ? "x" : "-",
                              Operatingday_Thursday = dateRange.DayNames.Contains("Thursday") ? "x" : "-",
                              Operatingday_Friday = dateRange.DayNames.Contains("Friday") ? "x" : "-",
                              Operatingday_Saturday = dateRange.DayNames.Contains("Saturday") ? "x" : "-",
                              Operatingday_Sunday = dateRange.DayNames.Contains("Sunday") ? "x" : "-"
                          };
  
                          pricingModel.Add(pricing);
  
                          dateRange = new DateRange { DayNames = new List&lt;string&gt;() };                        
                          continue;
                      }
  
      // if we get to here we have non consecutive  dates 
                      foreach (var optionPriceDate in o.Dates.Select(d=&gt;d.Date).OrderBy(d=&gt;d.Date))
                      {                                                
                          currentDate = optionPriceDate;
                          if (dateRange.Start == DateTime.MinValue) // new range
                          {
                              dateRange.Start = currentDate; 
                              dateRange.OptionPriceid = o.OptionPriceId;
                              dateRange.OptionPriceName = o.Name;
                              if (!dateRange.DayNames.Contains(currentDate.DayOfWeek.ToString()))
                              {
                                  dateRange.DayNames.Add(currentDate.DayOfWeek.ToString());
                              }                            
                              maxDate  = (from d in o.Dates select d.Date).Max(); 
                          }
  
                          if (currentDate == maxDate &amp;&amp; (maxDate-lastDate).Days == 1 ) //last consecative day
                          {
                              dateRange.End = currentDate;
                              if (!dateRange.DayNames.Contains(currentDate.DayOfWeek.ToString()))
                              {
                                  dateRange.DayNames.Add(currentDate.DayOfWeek.ToString());
                              }                     
                              Pricing pricing = new Pricing
                              {
                                  OptionId = option.OptionId,
                                  OptionName = option.Name,
                                  OptionPriceName = dateRange.OptionPriceName,
                                  Fromdate = dateRange.Start.ToShortDateString(),
                                  Todate = dateRange.End.ToShortDateString(),
                                  AdultPrice = o.AdultPrice,
                                  ChildPrice = o.ChildPrice,
                                  InfantPrice = o.InfantPrice,
                                  Operatingday_Monday = dateRange.DayNames.Contains("Monday") ? "x" : "-",
                                  Operatingday_Tuesday = dateRange.DayNames.Contains("Tuesday") ? "x" : "-",
                                  Operatingday_Wednesday = dateRange.DayNames.Contains("Wednesday") ? "x" : "-",
                                  Operatingday_Thursday = dateRange.DayNames.Contains("Thursday") ? "x" : "-",
                                  Operatingday_Friday = dateRange.DayNames.Contains("Friday") ? "x" : "-",
                                  Operatingday_Saturday = dateRange.DayNames.Contains("Saturday") ? "x" : "-",
                                  Operatingday_Sunday = dateRange.DayNames.Contains("Sunday") ? "x" : "-"
                              };
                              pricingModel.Add(pricing);
  
                              // END of Price band - Rset everything
                              dateRange = new DateRange
                              {
                                  Start = new DateTime(),
                                  End = new DateTime(),
                                  DayNames = new List&lt;string&gt;()
                              };
                              lastDate = DateTime.MinValue;
                              continue;
                          }
  
  
  
                          // Check to see if there is a gap
                          if ((currentDate.AddDays(-1) != lastDate) &amp;&amp; lastDate != DateTime.MinValue)
                          {
                              dateRange.End = lastDate;
  
                              Pricing pricing = new Pricing
                              {
                                  OptionId = option.OptionId,
                                  OptionName = option.Name,
                                  OptionPriceName = dateRange.OptionPriceName,
                                  Fromdate = dateRange.Start.ToShortDateString(),
                                  Todate = dateRange.End.ToShortDateString(),
                                  AdultPrice = o.AdultPrice,
                                  ChildPrice = o.ChildPrice,
                                  InfantPrice = o.InfantPrice,
                                  Operatingday_Monday = dateRange.DayNames.Contains("Monday") ? "x" : "-",
                                  Operatingday_Tuesday = dateRange.DayNames.Contains("Tuesday") ? "x" : "-",
                                  Operatingday_Wednesday = dateRange.DayNames.Contains("Wednesday") ? "x" : "-",
                                  Operatingday_Thursday = dateRange.DayNames.Contains("Thursday") ? "x" : "-",
                                  Operatingday_Friday = dateRange.DayNames.Contains("Friday") ? "x" : "-",
                                  Operatingday_Saturday = dateRange.DayNames.Contains("Saturday") ? "x" : "-",
                                  Operatingday_Sunday = dateRange.DayNames.Contains("Sunday") ? "x" : "-"
                              };
                              pricingModel.Add(pricing);                    
  
                              // Start New dateRange
                              dateRange = new DateRange
                              {
                                  Start = currentDate,
                                  End = new DateTime(),
                                  OptionPriceid = o.OptionPriceId,
                                  OptionPriceName = o.Name,
                                  DayNames = new List&lt;string&gt;()
                              };
                              dateRange.DayNames.Add(currentDate.DayOfWeek.ToString());
                              lastDate = currentDate;
                              continue;                                                                           
                          }
                          if (!dateRange.DayNames.Contains(currentDate.DayOfWeek.ToString()))
                          {
                              dateRange.DayNames.Add(currentDate.DayOfWeek.ToString());
                          }   
                          lastDate = currentDate;
                      }                                        
                  }
                  PricingList = pricingModel;
  </code></pre>