c#在一段时间内获得工作时间

时间:2017-11-15 07:49:12

标签: c# math timespan

考虑到多个时间跨度,我怎么能得到一个数组来告诉我说出工作时间的数量。

工作时间从09:00开始,到17:00结束

示例:

  1. 15-Nov-2017 16:00 - 2017年11月17日12:00 - >应该给我一个[1,8,3]

  2. 的数组
  3. 2017年11月15日09:00 - 2017年11月17日 - 12:00 - >应该给我一个[8,8,1]的数组(这似乎很简单,因为我可以做Hrs / 8和Hrs%8来得到结果。)

  4. 2017年11月16日星期五15:00 - 2017年11月17日15:00 - >应该给我一个[2,6]

  5. 的数组

    这是目前给我在开始时间和结束时间之间的总工作时间的方法:

    protected double getWorkingHrs(DateTime _dtTaskStart, DateTime _dtTaskEnd)
    {
        double count = 0;
    
        for (var i = _dtTaskStart; i < _dtTaskEnd; i = i.AddHours(1))
        {
            if (i.DayOfWeek != DayOfWeek.Saturday && i.DayOfWeek != DayOfWeek.Sunday)
            {
                if (i.TimeOfDay.Hours >= 9 && i.TimeOfDay.Hours < 17)
                {
                    count++;
                }
            }
        }
    
        return count;
    }
    

    任何帮助都将不胜感激。

    任务在8小时的时间内显示如下。因此,当我添加20小时任务时,我必须将它们分成几组并在网格中显示它们。我必须拆分它们,因为不同日期的任务可能被分配给不同的用户,并且可能有不同的注释等。

    UI for placing tasks

    干杯

2 个答案:

答案 0 :(得分:2)

以下是您的问题的解决方案:

    public static double[] GetWorkHours(DateTime start, DateTime end, TimeSpan workStartTime, TimeSpan workEndTime)
    {
        IList<double> result = new List<double>();

        if (start > end)
        {
            throw new ArgumentException("Start date is later than end date");
        }

        DateTime currentDate = start.Date;
        while (currentDate <= end.Date)
        {
            if (currentDate.DayOfWeek != DayOfWeek.Saturday && currentDate.DayOfWeek != DayOfWeek.Sunday)
            {
                TimeSpan realStartTime = GetStartTimeForDay(start, end, workStartTime, currentDate);
                TimeSpan realEndTime = GetEndTimeForDay(start, end, workEndTime, currentDate);

                if (realStartTime >= workEndTime || realEndTime <= workStartTime)
                {
                    result.Add(0);
                }
                else
                {
                    result.Add(GetHoursInTimePeriod(realStartTime, realEndTime));
                }
            }

            currentDate = currentDate.AddDays(1);
        }

        return result.ToArray();
    }

    private static TimeSpan GetStartTimeForDay(DateTime start, DateTime end, TimeSpan workStartTime, DateTime day)
    {
        return day == start.Date ? (start.TimeOfDay < workStartTime ? workStartTime : start.TimeOfDay) : workStartTime;
    }

    private static TimeSpan GetEndTimeForDay(DateTime start, DateTime end, TimeSpan workEndTime, DateTime day)
    {
        return day == end.Date ? (end.TimeOfDay < workEndTime ? end.TimeOfDay : workEndTime) : workEndTime;
    }

    private static double GetHoursInTimePeriod(TimeSpan start, TimeSpan end)
    {
        return (end - start).TotalHours;
    }

答案 1 :(得分:1)

虽然不是最漂亮的(通过添加小时来对日期时间进行棘轮循环是一种不太优雅的恕我直言。),您的功能可以调整为提供可计算的工作时数(或工作时间,因为它们通常被称为)每天如下:

protected IEnumerable<double> getWorkingHrsPerDay(DateTime _dtTaskStart, DateTime _dtTaskEnd)
{
    double count = 0;
    DateTime lastHandledDate = _dtTaskStart.Date;
    for (var i = _dtTaskStart; i < _dtTaskEnd; i = i.AddHours(1))
    {
        if (i.DayOfWeek != DayOfWeek.Saturday && i.DayOfWeek != DayOfWeek.Sunday)
        {
            if (i.TimeOfDay.Hours >= 9 && i.TimeOfDay.Hours < 17)
            {
                count++;
            }
        }
        //if we have started to count the hours for a new day
        if (lastHandledDate.Date != i.Date)
        {
            lastHandledDate = i.Date;
            double hourCount = count;
            //reset our hour count
            count = 0;
            //we return the count of the last day
            yield return hourCount;
        }
        lastHandledDate = i.Date;
    }
}

然后您可以使用LINQ的ToArray方法执行以下操作:

double[] hoursPerDay = getWorkingHrsPerDay(beginDate, endDate).ToArray();