Skip to main content
 首页 » 编程设计

c#之将单个日期的集合展平为日期范围

2024年02月24日49shihaiming

给定单日日期 (dd-mm-yyyy) 的数据表(如下图左侧所示)。

将其转换为范围集合的最优雅方法是什么,将每种类型的连续天数分组(显示在右侧)?

我们可以假设初始数据按 TypeID 排序,然后按日期排序。

TypeID  | Date            ->   TypeID  | Start      | End 
1       | 01/02/2010           1       | 01/02/2010 | 03/02/2010 
1       | 02/02/2010           2       | 03/02/2010 | 04/02/2010 
1       | 03/02/2010           2       | 06/02/2010 | 06/02/2010 
2       | 03/02/2010 
2       | 04/02/2010 
2       | 06/02/2010 

我对 LINQ 并不特别在意,但我认为这可能是可行的方法?

如有任何帮助,我们将不胜感激!

请您参考如下方法:

当然有人会想出一个简洁的 LINQ 解决方案,但这是我的旧式解决方案。当然它有问题并且无法应对所有组合,拼凑起来并解决了问题但在任何方面都不优雅:-(

internal class SourceData 
{ 
    public int TypeId { get; set; } 
    public DateTime Date { get; set; } 
} 
 
internal class Result 
{ 
    public int TypeId { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
} 
 
class Program 
{ 
 
    static void Main() 
    { 
 
        var a = new List<SourceData> { 
            new SourceData {TypeId = 1, Date = new DateTime(2010, 02, 01)}, 
            new SourceData {TypeId = 1, Date = new DateTime(2010, 02, 02)}, 
            new SourceData {TypeId = 1, Date = new DateTime(2010, 02, 03)},  
            new SourceData {TypeId = 2, Date = new DateTime(2010, 02, 03)},  
            new SourceData {TypeId = 2, Date = new DateTime(2010, 02, 04)},  
            new SourceData {TypeId = 2, Date = new DateTime(2010, 02, 06)}  
        }; 
 
        var results = new List<Result>(); 
        int currentTypeId = 1; 
        var rangeEndDate = new DateTime(); 
 
        DateTime rangeStartDate = a[0].Date; 
        DateTime currentDate = a[0].Date; 
 
        for (int i = 1; i < a.Count() ; i++) 
        { 
 
            if (a[i].TypeId != currentTypeId) 
            { 
                results.Add(new Result() { TypeId = currentTypeId, StartDate = rangeStartDate, EndDate = rangeEndDate }); 
                currentTypeId += 1;                     
                rangeStartDate = a[i].Date; 
            } 
 
            TimeSpan tSpan = a[i].Date - currentDate; 
            int differenceInDays = tSpan.Days; 
 
            if(differenceInDays > 1) 
            { 
                results.Add(new Result { TypeId = currentTypeId, StartDate = rangeStartDate, EndDate = a[i-1].Date }); 
                rangeStartDate = a[i].Date; 
            } 
 
            rangeEndDate = a[i].Date; 
            currentDate = a[i].Date; 
        } 
 
        results.Add(new Result { TypeId = currentTypeId, StartDate = rangeStartDate, EndDate = rangeEndDate }); 
 
        Console.WriteLine("Output\n"); 
        foreach (var r in results) 
            Console.WriteLine( string.Format( "{0} - {1} - {2}",r.TypeId,r.StartDate.ToShortDateString(),r.EndDate.ToShortDateString())); 
 
        Console.ReadLine(); 
 
    } 
} 

给出以下输出:-

输出

1 - 2010 年 1 月 2 日 - 2010 年 2 月 3 日

2 - 2010 年 2 月 3 日 - 2010 年 2 月 4 日

2 - 06/02/2010 - 06/02/2010