首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何找到两组非连续时间的交集?

如何找到两组非连续时间的交集?
EN

Stack Overflow用户
提问于 2012-01-17 00:19:59
回答 4查看 984关注 0票数 7

我正在尝试构建一个工具,它可以根据员工的工作时间和请假时间来计算配额。

我的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。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-17 00:40:06

正如InBetween提到的,有一些库已经解决了这个问题,但它们也解决了许多相关的问题。如果你只想解决这个特定的问题,而不想依赖另一个依赖,你可以尝试下面的方法。

代码语言:javascript
运行
复制
// 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);

这是一个基本的例子,尽管它可以被压缩(尽管可读性较差)和改进。

票数 2
EN

Stack Overflow用户

发布于 2012-01-17 00:29:33

CodeProject上查看这个很棒的article

对于你的具体问题来说,它可能太宽泛了,但它可能会给你一个很好的起点来解决它。

票数 3
EN

Stack Overflow用户

发布于 2012-01-17 01:48:30

我没有测试下面的代码,可能有一些bug,而且我用textpad写的可能有无效字符,想法很简单,我尝试使用有意义的变量。

代码语言:javascript
运行
复制
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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8882917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档