Check if a table contains overlapping timespans

I have a datatable with two columns FromDate and ToDate , which are in string format. I want to check if there are any duplicate records in my table.ie

From Date    To Date
----------------------      
9/01/2012    9/16/2012   
8/23/2012    8/24/2012   
8/25/2012    8/25/2012   
8/5/2012     8/6/2012    
8/26/2012    8/27/2012   
9/15/2012    9/23/2012

The table contains duplicate records as their date range is mapping for

From Date       To Date      
----------------------      
9/01/2012    9/16/2012   
9/15/2012    9/23/2012

It should return false.


var query = from row in dt.AsEnumerable()
            from row1 in dt.AsEnumerable()
            where
            (

                 (
                     DateTime.Parse(row1.Field<string>("fromDate")) >= DateTime.Parse(row.Field<string>("fromDate")) &&
                     DateTime.Parse(row1.Field<string>("fromDate")) <= DateTime.Parse(row.Field<string>("toDate"))
                 )
                 ||
                 (
                     DateTime.Parse(row1.Field<string>("toDate")) >= DateTime.Parse(row.Field<string>("fromDate")) &&
                     DateTime.Parse(row1.Field<string>("toDate")) <= DateTime.Parse(row.Field<string>("toDate"))
                 )
            )
            select new
            {
                fromDate = DateTime.Parse(row1.Field<string>("fromDate")),
                toDate = DateTime.Parse(row1.Field<string>("toDate"))
            };
//This lst contains the dates which are overlapping    
var lst = query.Distinct().ToList();

Okay then, a selfjoin will help here:

I have a small class TimePeriod, just to meet your needs

public class TimePeriod
{
    public int Id;
    public DateTime FromDate { get; set; }

    public DateTime ToDate { get; set; }

    public static DateTime Parse(string date)
    {
        var dt = DateTime.Parse(date, 
        CultureInfo.CreateSpecificCulture("en-US"), DateTimeStyles.RoundtripKind);
        return dt;
    }
}

then I have some TestData

var list = new List();

        list.Add(new TimePeriod() { Id = 1, FromDate = TimePeriod.Parse("9/01/2012"),  ToDate = TimePeriod.Parse("9/16/2012") });
        list.Add(new TimePeriod() { Id = 2, FromDate = TimePeriod.Parse("8/23/2012"), ToDate = TimePeriod.Parse("8/24/2012") });
        list.Add(new TimePeriod() { Id = 3, FromDate = TimePeriod.Parse("8/25/2012"), ToDate = TimePeriod.Parse("8/25/2012") });
        list.Add(new TimePeriod() { Id = 4, FromDate = TimePeriod.Parse("8/5/2012"), ToDate = TimePeriod.Parse("8/6/2012") });
        list.Add(new TimePeriod() { Id = 5, FromDate = TimePeriod.Parse("8/26/2012"), ToDate = TimePeriod.Parse("8/27/2012") });
        list.Add(new TimePeriod() { Id = 6, FromDate = TimePeriod.Parse("9/15/2012"), ToDate = TimePeriod.Parse("9/23/2012") });

And here is the solution: (with some inspiration of OraNob, thanks for that)

var overlaps = from current in list
            from compare in list
            where
            (
            (compare.FromDate > current.FromDate &&
            compare.FromDate < current.ToDate) ||
            (compare.ToDate > current.FromDate &&
            compare.ToDate < current.ToDate)
            )
            select new
            {
                Id1 = current.Id,
                Id2 = compare.Id,
            };

Perhaps you want to leave out the second Id (as you will have duplicates here ( 1 / 6) and (6 / 1)


Sort by ToDate , FromDate (or build a sorted array of indexes into your DataTable). Loop from row or array position #2 to the end and see if the FromDate <= to the previous item's ToDate. Place overlapping items into a list. Job done.

You can also sort by FromDate , ToDate and do similar logic.

链接地址: http://www.djcxy.com/p/11012.html

上一篇: 如何访问d3 SVG元素的数据

下一篇: 检查一个表是否包含重叠时间段