从日期集合C#中查找日期范围

简单的问题。 我有一个有序的日期集合。 他们是英国约会顺便说一句

01/01/10 01/02/10 01/03/10 01/04/10 02/04/10 03/04/10 04/04/10 

我想将其转换为日期范围的集合

 01/01/10 -> 01/01/10 01/02/10 -> 01/02/10 01/03/10 -> 01/03/10 01/04/10 -> 04/04/10 

只是为了澄清,我正在尝试将任何连续日期转换为范围。 因此前3个日期是独立的,最后4个日期将转换为4月1日至4月4日的范围。

现在我可以使用循环来做到这一点,但它不是很优雅。 有没有人有任何解决方案?

谢谢

鉴于您想要确定连续日期范围的范围,我认为您唯一的选择是,如您所说的循环。 您可以在一次传递中执行此操作,并将其放在扩展方法中,以便它可以在任何IList ,例如:

 // purely an example, chances are this will have actual, y'know logic in live public class DateRange { private List dates = new List(); public void Add(DateTime date) { this.dates.Add(date); } public IEnumerable Dates { get { return this.dates; } } } public static IEnumerable GetRanges(this IList dates) { List ranges = new List(); DateRange currentRange = null; // this presumes a list of dates ordered by day, if not then the list will need sorting first for( int i = 0; i < dates.Count; ++i ) { var currentDate = dates[i]; if( i == 0 || dates[i - 1] != currentDate.AddDays(-1)) { // it's either the first date or the current date isn't consecutive to the previous so a new range is needed currentRange = new DateRange(); ranges.Add(currentRange); } currentRange.Add(currentDate); } return ranges; } 

您还可以通过传入IEnumerable使其更通用:

 public static IEnumerable GetRanges(this IEnumerable dates) { List ranges = new List(); DateRange currentRange = null; DateTime? previousDate = null; // this presumes a list of dates ordered by day, if not then the list will need sorting first foreach( var currentDate in dates ) { if( previousDate == null || previousDate.Value != currentDate.AddDays(-1) ) { // it's either the first date or the current date isn't consecutive to the previous so a new range is needed currentRange = new DateRange(); ranges.Add(currentRange); } currentRange.Add(currentDate); previousDate = currentDate; } return ranges; } 
 dates.Aggregate(new List(), (acc, dt) => { if (acc.Count > 0 && acc.Last().d2 == dt.AddDays(-1)) acc[acc.Count - 1].d2 = dt; else acc.Add(new DateRange(dt, dt)); return acc; } ); 

其中DateRange是这样的类:

 class DateRange { public DateTime d1, d2; public DateRange(DateTime d1, DateTime d2) { this.d1 = d1; this.d2 = d2; } } 
 var stringDates = new List {"01/09/10", "31/08/10", "01/01/10"}; var dates = stringDates.ConvertAll(DateTime.Parse); dates.Sort(); var lastDateInSequence = new DateTime(); var firstDateInSequence = new DateTime(); foreach (var range in dates.GroupBy( d => { if ((d - lastDateInSequence).TotalDays != 1) firstDateInSequence = d; lastDateInSequence = d; return firstDateInSequence; })) { var sb = new StringBuilder(); sb.Append(range.First().ToShortDateString()); sb.Append(" => "); sb.Append(range.Last().ToShortDateString()); Console.WriteLine(sb.ToString()); }