Я изо всех сил пытаюсь обдумать это.
У меня есть List<Appointment>
, который содержит DateTime Start
и DateTime End
вместе с несколькими другими битами.
Iхочу нарисовать ежедневник, который перечисляет все встречи в порядке с заполнителями / пробелами, где это уместно.
Я справился с этим, но теперь мне нужно разобраться со сценарием, когда встречи перекрываются.Кажется, это может быть;
- встреча a начинается до и заканчивается после встречи b
- встреча a начинается до и заканчивается во время встречи b
- встреча a начинается во время и заканчивается после встречи b
- встреча начинается во время и заканчивается во время встречи b
Это похоже на проблему, которая должна была быть решена ранее.Есть указатели?
Вот пример какого-то ужасного кода, над которым я сейчас работаю;
List<TechActivityModel> techActivity = new TechService().GetTechActivity(7, new DateTime(2018, 4, 11), new DateTime(2018, 4, 11).AddDays(1))
.OrderBy(t => t.Start).ToList();
for (int i = techActivity.Count - 1; i >= 0; i--)
{
//something starts before and ends after
TechActivityModel clash = techActivity.Where(t => t.Id != techActivity[i].Id && t.Start < techActivity[i].Start && t.End > techActivity[i].End).FirstOrDefault();
while (clash != null)
{
//split the clashing activity into a task before and another task after the existing on
//first create the 2nd part of the task (after the existing one)
TechActivityModel activityContinued = new TechActivityModel()
{
Start = techActivity[i].End,
End = clash.End,
Subject = "++" + clash.Subject
};
activityContinued.Length = (int)(activityContinued.End - activityContinued.Start).TotalMinutes;
techActivity.Add(activityContinued);
//update the clashing task to finish when the existing task starts
clash.Subject = "+" + clash.Subject;
clash.End = techActivity[i].Start;
clash.Length = (int)(clash.End - clash.Start).TotalMinutes;
clash = techActivity.Where(t => t.Id != techActivity[i].Id && t.Start < techActivity[i].Start && t.End > techActivity[i].End).FirstOrDefault();
}
}
for (int i = techActivity.Count - 1; i >= 0; i--)
{
//something starts before and ends during
TechActivityModel clash = techActivity.Where(t => t.Id != techActivity[i].Id && t.Start <= techActivity[i].Start && t.End > techActivity[i].Start).FirstOrDefault();
while (clash != null)
{
//update the clashing task to finish when the existing task starts
clash.Subject = "/" + clash.Subject;
clash.End = techActivity[i].Start;
clash.Length = (int)(clash.End - clash.Start).TotalMinutes;
clash = techActivity.Where(t => t.Id != techActivity[i].Id && t.Start < techActivity[i].Start && t.End > techActivity[i].Start).FirstOrDefault();
}
}
techActivity = techActivity.OrderBy(t => t.Start).ToList();
//now we're going to pad all the gaps
List<TechActivityModel> newList = new List<TechActivityModel>();
DateTime LastEnd = techActivity[0].End;
//start with the gap from midnight till the first task
newList.Add(new TechActivityModel()
{
Start = new DateTime(2018, 4, 10),
End = techActivity[0].Start,
TicketNumber = 0,
Note = "",
TicketSubject = "",
TimeLogged = 0,
Id = 0
}
);
//pad all the gaps
for (int i = 1; i < techActivity.Count; i++)
{
if (LastEnd < techActivity[i].Start.AddMinutes(-2))
{
TechActivityModel gap = new TechActivityModel()
{
Start = LastEnd.AddMinutes(1),
End = techActivity[i].Start,
Subject = "",
Id = 0
};
gap.Length = (int)(gap.End - gap.Start).TotalMinutes;
newList.Add(gap);
}
LastEnd = techActivity[i].End;
}
//and finally fill the gap from the last task till midnight
newList.Add(new TechActivityModel()
{
Start = LastEnd,
End = new DateTime(2018, 4, 11),
Subject = "",
Length = 0
}
);
newList.AddRange(techActivity);
string content = "";
foreach (TechActivityModel techActivityModel in newList.OrderBy(t => t.Start))
{
content +=
techActivityModel.Start.ToShortTimeString()
+ " - " + techActivityModel.End.ToShortTimeString()
+ " (" + techActivityModel.Length + "mins)"
+ " : " + techActivityModel.Subject
+ Environment.NewLine;
}