我正在尝试构建一个工具,它可以根据员工的工作时间和请假时间来计算配额。
我的ShiftSet对象是一组Shift对象,它们由StartTime和EndTime (都是time(7)类型)组成。每个ShiftSet对应一天。
ScheduleExceptions是员工休假的时间。一天中可以有任意数量的重叠或非重叠的ScheduleExceptions。它们属于datetime数据类型。
ShiftSet的一个示例:
08:00-10:00
10:00-12:00
13:00-15:00
15:00-17:00
同一天的ScheduleExceptions示例:
07:30-10:30
14:35-16:00
我需要做的是找出员工一天的工作时间。我能想到的方法是计算ShiftSet和ScheduleExceptions的逆的交集。
我该如何利用时间做到这一点呢?如果可能的话,我更喜欢使用Linq。
发布于 2012-01-17 00:40:06
正如InBetween提到的,有一些库已经解决了这个问题,但它们也解决了许多相关的问题。如果你只想解决这个特定的问题,而不想依赖另一个依赖,你可以尝试下面的方法。
// Finds ones with absolutely no overlap
var unmodified = shifts.Where(s => !exceptions.Any(e => s.Start < e.End && s.End > e.Start));
// Finds ones entirely overlapped
var overlapped = shifts.Where(s => exceptions.Any(e => e.End >= s.End && e.Start <= s.Start));
// Adjusted shifts
var adjusted = shifts.Where(s => !unmodified.Contains(s) && !overlapped.Contains(s))
.Select(s => new Shift
{
Start = exceptions.Where(e => e.Start <= s.Start && e.End > s.Start).Any() ? exceptions.Where(e => e.Start <= s.Start && e.End > s.Start).First().End : s.Start,
End = exceptions.Where(e => e.Start < s.End && e.End >= s.End).Any() ? exceptions.Where(e => e.Start < s.End && e.End >= s.End).First().Start : s.End
});
var newShiftSet = unmodified.Union(overlapped).Union(adjusted);这是一个基本的例子,尽管它可以被压缩(尽管可读性较差)和改进。
发布于 2012-01-17 00:29:33
在CodeProject上查看这个很棒的article
对于你的具体问题来说,它可能太宽泛了,但它可能会给你一个很好的起点来解决它。
发布于 2012-01-17 01:48:30
我没有测试下面的代码,可能有一些bug,而且我用textpad写的可能有无效字符,想法很简单,我尝试使用有意义的变量。
var orderedShifts = ShiftSets.OrderBy(x=>x.StartDate).ToList();
var compactShifts = new List<Shift>();
compactShifts.Add(orderedShifs[0]);
foreach (var item in orderedShift)
{
if (item.Start <= compactShifts[compactShifts.Count-1].End
&& item.End > compactShifts[compactShifts.Count-1].End)
{
compactShifts[compactShifts.Count-1].End = item.End;
}
else if (item.Start > compactShifts[compactShifts.Count-1].End)
compactShifts.Add(item);
}
//run similar procedure for schedule exceptions to create compact schedules.
var validShifts = new List<Shift>();
foreach (var item in compactShifts)
{
var shiftCheatingPart = compactExceptions
.FirstOrDefault(x=>x.Start < item.Start
&& x.End > item.End)
if (shiftCheatingPart != null)
{
if (item.End <= shiftCheatingPart.End)
continue;
validShifts.Add(new Shift{Start = shiftCheatingPart.End,End = item.End);
}
}
var totalTimes = validShifts.Sum(x=>x.End.Sunbtract(x.Start).TotalHours);https://stackoverflow.com/questions/8882917
复制相似问题