从具有重叠场景的日期持续时间获取周数

Get the no of weeks from date duration with overlapping scenario

我需要计算员工的总分配周数和总替补周数。

一名员工在某个时间段内被分配到不同的项目中,该时间段总是从星期一开始,总是在星期五结束。周一至周五将被视为 1 week.There 任何项目的持续时间都不能超过 2 周。应调整分配状态的任何重叠周。如果分配了员工状态,并且该持续时间与任何替补周持续时间重叠或下降,则根本不应计算替补状态的该周持续时间。

以下为相关场景

"AssignedHistory":[ 
   {"Project":1,"status":"Assigned","Startdate":"01/03/2022", "Enddate":"01/07/2022" }, 
   {"Project":2,"status":"Assigned","Startdate":"01/10/2022", "Enddate":"01/14/2022" }, 
   {"Project":3,"status":"Assigned", "Startdate":"01/10/2022", "Enddate":"01/21/2022" },
   {"Project":4,"status":"Assigned", "Startdate":"02/21/2022", "Enddate":"02/25/2022" },       
   {"Project":5,"status":"Bench","Startdate":"01/17/2022", "Enddate":"01/21/2022" },
   {"Project":6,"status":"Bench","Startdate":"02/07/2022", "Enddate":"02/11/2022" }
   {"Project":7,"status":"Bench","Startdate":"02/21/2022", "Enddate":"03/04/2022" }    
]

在这里我需要找到员工的总分配周数和总替补周数,预期结果应该是:

Total assigned week:4
Total benched week :1



     Since 1 week of assigned status is overlapping for 2 projects(no2 and no 3) from 10th Jan to 14 Jan so project 2 and 3 together will be counted as 2 .Also for assigned week of  project 3  it is overlapping with  benched week of  project 5  from 17th Jan to 21st Jan so in that case bench week for project 5 will be counted as 0.Similarly for assigned week of project 4,duration from 21st feb to 25th feb is overlapping or falls under benched week of  project 7 so in this case project 7 will be counted as 0.So only we have project 6 for benched week which doest not overlaps with any of the assined project duration.

这就是为什么总替补人数为 1 的原因。

我是这么想的

 var assignedweek = AssignedHistory.Where(x => new []{"Assigned"}.Contains(x.status)).ToList();
    var benchedweek = AssignedHistory.Where(x => new []{"Bench"}.Contains(x.status)).ToList();
     
    List<DateTime> AssignedWeeklist = assignedweek
        .SelectMany(a => {
            DateTime firstSunday = a.Startdate.AddDays(-(int)a.Startdate.DayOfWeek);
            DateTime lastSunday = a.Enddate.AddDays(-(int)a.Enddate.DayOfWeek); 
            int weeks = (lastSunday - firstSunday).Days / 7 + 1;
    
            // Enumerate one Sunday per week
            return Enumerable.Range(0, weeks).Select(i => firstSunday.AddDays(7 * i));
        })
        .Distinct()
        .ToList();
        
        List<DateTime> BenchWeeklist = benchedweek
        .SelectMany(a => {
            DateTime firstSunday = a.Startdate.AddDays(-(int)a.Startdate.DayOfWeek);
            DateTime lastSunday = a.Enddate.AddDays(-(int)a.Enddate.DayOfWeek); 
            int weeks = (lastSunday - firstSunday).Days / 7 + 1;
    
            // Enumerate one Sunday per week
            return Enumerable.Range(0, weeks).Select(i => firstSunday.AddDays(7 * i));
        })
        .Distinct()
        .ToList();
        
        int assignedweekcount = AssignedWeeklist.Count();
        int benchedweekcount = BenchWeeklist.Except(AssignedWeeklist).Count();

它给出了正确的分配周数但是如果替补周与分配的周有重叠,它给出的替补周数不正确。 有什么办法吗?

你必须在 benchweek 更改你的计算逻辑,你必须按项目保留星期日日期:

(我有 OS 法语,所以示例中的日期格式为 DD/MM/YYYY 而不是 MM/DD/YYYY)

        var AssignedHistory1 = new List<Projet>()
        {
            new Projet(1,"Assigned","03/01/2022", "07/01/2022" ),
            new Projet(2,"Assigned","10/01/2022", "14/01/2022" ),
            new Projet(3,"Assigned","10/01/2022", "21/01/2022" ),
            new Projet(4,"Assigned","21/02/2022", "25/02/2022" ),
            new Projet(5,"Bench", "17/01/2022", "21/01/2022" ),
            new Projet(6,"Bench", "07/02/2022", "11/02/2022" ),
            new Projet(7,"Bench", "21/02/2022", "04/03/2022" )
        };
        var AssignedHistory2 = new List<Projet>()
        {
            new Projet(1,"Assigned","17/01/2022", "28/01/2022" ),
            new Projet(2,"Bench", "10/01/2022", "21/01/2022" )
        };
        var AssignedHistory3 = new List<Projet>()
        {
            new Projet(1,"Assigned","07/02/2022", "18/02/2022" ),
            new Projet(2,"Bench", "14/02/2022", "25/02/2022" )
        };

        var listsamples = new List<List<Projet>> { AssignedHistory1, AssignedHistory2, AssignedHistory3 };
        for(int i = 0; i < listsamples.Count;i++)
        {
            calculate(listsamples[i], $"Sample Assigned{i+1}");
        }

        void calculate(List<Projet> AssignedHistory, string txt)
        {
            var assignedweek = AssignedHistory.Where(x => new[] { "Assigned" }.Contains(x.Status)).ToList();
            var benchedweek = AssignedHistory.Where(x => new[] { "Bench" }.Contains(x.Status)).ToList();
            List<DateTime> AssignedWeeklist = assignedweek
            .SelectMany(a =>
            {
                DateTime firstSunday = a.StartDate.AddDays(-(int)a.StartDate.DayOfWeek);
                DateTime lastSunday = a.EndDate.AddDays(-(int)a.EndDate.DayOfWeek);
                int weeks = (lastSunday - firstSunday).Days / 7 + 1;

            // Enumerate one Sunday per week
            return Enumerable.Range(0, weeks).Select(i => firstSunday.AddDays(7 * i));
            })
    .Distinct()
    .ToList();

            List<List<DateTime>> BenchWeeklist = benchedweek
            .Select(a =>
            {
                DateTime firstSunday = a.StartDate.AddDays(-(int)a.StartDate.DayOfWeek);
                DateTime lastSunday = a.EndDate.AddDays(-(int)a.EndDate.DayOfWeek);
                int weeks = (lastSunday - firstSunday).Days / 7 + 1;

            // Enumerate one Sunday per week
            return new List<DateTime>() { firstSunday, lastSunday }.Distinct().ToList();
            })
            .Distinct()
            .ToList();

            int assignedweekcount = AssignedWeeklist.Count();
            var benchedweekcount = 0;

            foreach (var l in BenchWeeklist)
            {
                var found = false;
                foreach (var it in l)
                {
                    if (AssignedWeeklist.Contains(it)) found = true;
                }
                if (!found) benchedweekcount++;
            }

            Console.WriteLine($"AssignedWeek{n} count: {assignedweekcount}, BenchWeek{n} count: {benchedweekcount}");
        }

结果:

AssignedWeek1 count: 4, BenchWeek1 count: 1
AssignedWeek2 count: 2, BenchWeek2 count: 0
AssignedWeek3 count: 2, BenchWeek3 count: 0