C#计算给定时间段内的最长加班时间

时间:2017-05-03 16:51:49

标签: c# datetime time

我的日历正在使用Shift类,如下所示:

public class Shift
{
    public TimeSpan Start { get; private set; } //e.g. 08:00
    public TimeSpan End { get; private set; } //e.g. 17:00
    public DateTime Day { get; } //e.g. 23.3. 2015
}

日历类如下所示:

 public class Calendar
 {
    public Shift[] ShiftsOfEmployee { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public Calendar(DateTime startDate, DateTime endDate)
    {
        StartDate = startDate;
        EndDate = endDate;
        ShiftsOfEmployee = new Shift[Length()];
    }

    public int Length()
    {
        return (EndDate - StartDate).Days;
    }

    public void calculateMaximumOvertime()
    { 
        //TODO 
    }
 }

我现在要做的是calculateMaximumOvertime函数。我想通过计算周数(例如int weeks = (EndDate - StartDate).TotalDays / 7;)来做到这一点,然后每周创建一个结果列表。然后逐日通过ShiftsOfEmployee并将每个Shift的值(如果有,否则为0)添加到相应的周。然后我将不得不再次通过结果列表并选择最大值。所有这些在我看来有点笨拙,我在想是否有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

您可以将问题分成两部分:查找日历周并计算总和。

您可以使用Calendar.GetWeekOfYear来解决第一个问题。然后,您可以使用Linq以set方式汇总数据。

DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
var cal = dfi.Calendar;

var shiftWeeks = from se in ShiftsOfEmployee
                 group se by cal.GetWeekOfYear(se.Day, dfi.CalendarWeekRule, dfi.FirstDayOfWeek)
                   into g
                 select new
                 {
                     WeekNumber = g.Key,
                     Units = g.Sum(s => Units(s.Start, s.End))
                 };

 var max = shiftWeeks.Max(wk => wk.Units);

 public static int Units(TimeSpan start, TimeSpan end) { ... }

或者,如果您想要每周最大值

var shiftWeeks = from se in ShiftsOfEmployee
                 group se by cal.GetWeekOfYear(se.Day, dfi.CalendarWeekRule, dfi.FirstDayOfWeek)
                   into g
                 select new
                 {
                     WeekNumber = g.Key,
                     Max = g.Max(s => Units(s.Start, s.End))
                 };

答案 1 :(得分:0)

如果天数不是七分之一,那么将这些星期划分为不会很好。解决这个问题的一个更好的方法是将每个班次添加到一个列表中,并在每次添加班次时都有一个计数器增量,一旦达到7,创建另一个代表下周的列表并重置计数器,然后继续这样做直到所有轮班已被添加到“周”。然后你可以处理最大的加班时间。

public void calculateMaximumOvertime()
{
    List<Shift[]> ShiftsByWeek = new List<Shift[]>();
    int count = 0;
    Shift[] adder = new Shift[6];
    foreach (var shift in ShiftsOfEmployee)
    {
        adder.SetValue(shift, count);
        count++;
        if (count == 6)
        {
            Shift[] temp = new Shift[6];
            adder.CopyTo(temp, 0);
            ShiftsByWeek.Add(temp);
            Array.Clear(adder, 0 , adder.Length);
            count = 0;
        }
    }
}

编辑:此方法没有考虑星期几,但由于星期几是基于位置的,您可以设计代表一周班次的数组,每个索引代表一周中的某一天,这样< / p>

Week[0] = sunday
Week[1] = monday
Week[2] = tuesday

等等。