C# calculate date ranges from a list of dates
Given a list of dates (which may not be sorted), I want to build a list of date ranges -
E.g. Assuming MM/DD format,
Input - 5/1, 5/5, 5/6, 5/15, 5/7, 5/8, 5/19,5/20, 5/23
Output -
Date Range 1: 5/1 to 5/1 Date Ra开发者_StackOverflownge 2: 5/5 to 5/8 Date Range 3: 5/15 to 5/15 Date Range 4: 5/19 to 5/20 Date Range 5: 5/23 to 5/23
Basically, a range should be continuous.
- Sort the dates
- Start a range containing the next date (to start with it will be the first one)
- Is the second "valid" date the next date which would be in the range? If so, keep going. If not, close the current range and start a new one.
- Repeat until you've run out of dates, at which point you close the current range and you're done.
You can create a list of DateTime
(possibly using the same year for them all) and sort it.
It is then fairly easy to find if a day and the next day exist in the list (using DateTime.AddDays(1)
).
public class DateRange
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
[TestClass]
public class DateRangerTest
{
private List<DateRange> GetDateRanges(List<DateTime> dates)
{
if (dates == null || !dates.Any()) return null;
dates = dates.OrderBy(x => x.Date).ToList();
var dateRangeList = new List<DateRange>();
DateRange dateRange = null;
for (var i = 0; i < dates.Count; i++)
{
if (dateRange == null)
{
dateRange = new DateRange { Start = dates[i] };
}
if (i == dates.Count - 1 || dates[i].Date.AddDays(1) != dates[i + 1].Date)
{
dateRange.End = dates[i].Date;
dateRangeList.Add(dateRange);
dateRange = null;
}
}
return dateRangeList;
}
[TestMethod]
public void GetDateRanges_MultiDateRangeTest()
{
var dates = new List<DateTime>
{
new DateTime(1999,5,1),
new DateTime(1999,5,5),
new DateTime(1999,5,6),
new DateTime(1999,5,15),
new DateTime(1999,5,7),
new DateTime(1999,5,8),
new DateTime(1999,5,19),
new DateTime(1999,5,20),
new DateTime(1999,5,23)
};
var dateRanges = GetDateRanges(dates);
Assert.AreEqual(new DateTime(1999, 5, 1), dateRanges[0].Start);
Assert.AreEqual(new DateTime(1999, 5, 1), dateRanges[0].End);
Assert.AreEqual(new DateTime(1999, 5, 5), dateRanges[1].Start);
Assert.AreEqual(new DateTime(1999, 5, 8), dateRanges[1].End);
Assert.AreEqual(new DateTime(1999, 5, 15), dateRanges[2].Start);
Assert.AreEqual(new DateTime(1999, 5, 15), dateRanges[2].End);
Assert.AreEqual(new DateTime(1999, 5, 19), dateRanges[3].Start);
Assert.AreEqual(new DateTime(1999, 5, 20), dateRanges[3].End);
Assert.AreEqual(new DateTime(1999, 5, 23), dateRanges[4].Start);
Assert.AreEqual(new DateTime(1999, 5, 23), dateRanges[4].End);
}
}
精彩评论