简单的问题。我有一个有序的日期集合。他们是英国约会btw
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日的范围。
现在我可以使用循环来做到这一点,但它不是很优雅。有没有人有任何解决方案?
由于
答案 0 :(得分:5)
鉴于您要确定连续日期范围的范围,我认为您唯一的选择是,正如您所说的循环。您可以在一次通过中执行此操作,并将其放在扩展方法中,以便它可以在任何IList<DateTime>
上运行,例如:
// purely an example, chances are this will have actual, y'know logic in live
public class DateRange
{
private List<DateTime> dates = new List<DateTime>();
public void Add(DateTime date)
{
this.dates.Add(date);
}
public IEnumerable<DateTime> Dates
{
get { return this.dates; }
}
}
public static IEnumerable<DateRange> GetRanges(this IList<DateTime> dates)
{
List<DateRange> ranges = new List<DateRange>();
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<DateTime>
:
public static IEnumerable<DateRange> GetRanges(this IEnumerable<DateTime> dates)
{
List<DateRange> ranges = new List<DateRange>();
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;
}
答案 1 :(得分:0)
var stringDates = new List<string> {"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());
}
答案 2 :(得分:0)
dates.Aggregate(new List<DateRange>(), (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;
}
}