我需要計算員工的總分配周數和總替補周數。
員工在某個時間段內被分配到不同的專案中,該時間段總是從星期一開始,總是在星期五結束。周一至周五將被視為 1 周。如果員工在分配狀態周專案中作業并且該專案持續時間屬于固定狀態周專案,則分配狀態的任何重疊周應視為 1 周,因此該周將不計入總長凳周數。
下面是相關的場景如下。
"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":"Bench","Startdate":"01/17/2022", "Enddate":"01/21/2022" },
{"Project":5,"status":"Bench","Startdate":"02/07/2022", "Enddate":"02/11/2022" }
]
在這里,我需要找到員工的總分配周數和總替補周數,預期結果應該是:
Total assigned week:3
Total benched week :1
由于 1 周的分配狀態與 1 月 10 日至 1 月 14 日的 2 個專案重疊,并且專案 4 的基準周與 1 月 17 日至 1 月 21 日的專案 3 的分配狀態重疊。
這就是我正在嘗試的方式
var assignedweek = AssignedHistory.Where(x => new []{"Assigned"}.Contains(x.status)).ToList();
var benchedweek = AssignedHistory.Where(x => new []{"Bench"}.Contains(x.status)).ToList();
int AssignedWeekCount = 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()
.Count();
int BenchWeekCount = 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()
.Count();
但如果板凳周與指定周重疊,則會給出不正確的板凳周計數。我無法從替補周中洗掉重疊的一周。
任何建議將不勝感激。
uj5u.com熱心網友回復:
我認為這會有所幫助。這是計算重疊周數的公式,其中分配的周與基準周重疊。
這個公式將計算有多少個基準周與它們重疊,您可以從基準周數中減去。
var overlappingWeeks = benchedweek.Where(b => assignedweek.Any(
a => a.Startdate < b.Enddate && a.Enddate > b.Startdate)
)
.Select(b => b.Startdate)
.Distinct()
.Count();
ETA:我忘記了同一周可能有多個板凳周,而我的公式會將它們全部計算在內!所以我添加Select了一個Distinct.
讓我知道這在您的場景中是如何作業的:我是從記憶中完成的,因此尚未經過測驗。
uj5u.com熱心網友回復:
可能你創建這樣的周結構會很有趣:
public class Week
{
public int WeekId { get; private set; }
private DateTime FirstDayOfWeek {get; set; }
private const int numDayInWeek = 7;
public Week(Week anotherWeek): this(anotherWeek.FirstDayOfWeek)
{
}
public Week(DateTime date)
{
FirstDayOfWeek = GetFirstDateOfWeek(date);
var numWeekInYear = GetIndexWeekInYearForFirstDayOfWeek(date);
WeekId = GenerateWeekId(numWeekInYear, FirstDayOfWeek.Year);
}
private int GetIndexWeekInYearForFirstDayOfWeek(DateTime date)
{
return (GetFirstDateOfWeek(date).DayOfYear - 1) / numDayInWeek 1;
}
private DateTime GetFirstDateOfWeek(DateTime date)
{
return date.AddDays(-(int)date.DayOfWeek);
}
private int GenerateWeekId(int numWeekInYear, int year)
{
return year * 100 numWeekInYear;
}
public static List<Week> operator -(Week last, Week first)
{
List<Week> ret = new List<Week>();
if (last.WeekId < first.WeekId)
return ret;
for(Week cursor = first; cursor <= last; cursor )
ret.Add(cursor);
return ret;
}
public static Week operator (Week current)
{
return new Week(current.FirstDayOfWeek.AddDays(numDayInWeek));
}
public static bool operator >= (Week left, Week right)
{
return left.FirstDayOfWeek >= right.FirstDayOfWeek;
}
public static bool operator <= (Week left, Week right)
{
return left.FirstDayOfWeek <= right.FirstDayOfWeek;
}
public override int GetHashCode()
{
return WeekId;
}
public override bool Equals(object obj)
{
return Equals(obj as Week);
}
public bool Equals(Week obj)
{
return obj != null && obj.WeekId == this.WeekId;
}
}
并像這樣使用這個結構:
internal class ProjectDataCalculator
{
public List<Week> GetProjectDataWeeks(ProjectData projectData)
{
return new Week(projectData.EndDate) - new Week(projectData.StartDate);
}
public ProjectReport GetProjectReport(List<ProjectData> projectDatas)
{
ProjectReport report = new ProjectReport();
foreach (var projectData in projectDatas)
{
foreach (var week in GetProjectDataWeeks(projectData))
{
DefineWeekAssigned(report, projectData.Assigned, week);
}
}
return report;
}
private void DefineWeekAssigned(ProjectReport report, ProjectDataStatus assigned, Week week)
{
if(report.WeeksStatus.ContainsKey(week))
{
if (assigned == ProjectDataStatus.Assigned)
report.WeeksStatus[week] = assigned;
} else
{
report.WeeksStatus[week] = assigned;
}
}
}
internal class ProjectReport {
public Dictionary<Week, ProjectDataStatus> WeeksStatus { get; set; } = new Dictionary<Week, ProjectDataStatus>();
}
enum ProjectDataStatus
{
Assigned,
Bench
}
internal class ProjectData
{
public int Project { get; set; }
public ProjectDataStatus Assigned { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/409442.html
標籤:
