c#在一段时间内完成工作时间

c#在一段时间内完成工作时间,c#,math,timespan,C#,Math,Timespan,给定多个时间跨度,我如何获得一个数组,该数组告诉我一次发言的工作小时数 工作时间从09:00开始,到17:00结束 示例: 2017年11月15日16:00-2017年11月17日12:00->应该给我一个[1,8,3]数组 2017年11月15日09:00-2017年11月17日12:00->应该给我一个[8,8,1]数组(这似乎很容易,因为我可以做Hrs/8和Hrs%8得到结果。) 2017年11月16日15:00-2017年11月17日15:00->应该给我一个[2,6]数组 这是当前为我

给定多个时间跨度,我如何获得一个数组,该数组告诉我一次发言的工作小时数

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

示例:

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

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

  • 2017年11月16日15:00-2017年11月17日15:00->应该给我一个[2,6]数组

  • 这是当前为我提供开始时间和结束时间之间总工作小时数的方法:

    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;
    }
    
    受保护的双getWorkingHrs(日期时间\u dtTaskStart,日期时间\u dtTaskEnd)
    {
    重复计数=0;
    对于(变量i=\u dtTaskStart;i<\u dttasksend;i=i.AddHours(1))
    {
    如果(i.DayOfWeek!=星期六和i.DayOfWeek!=星期日、星期日)
    {
    如果(i.TimeOfDay.Hours>=9和&i.TimeOfDay.Hours<17)
    {
    计数++;
    }
    }
    }
    返回计数;
    }
    
    任何帮助都将不胜感激

    任务在8小时内显示为这样。因此,当我添加一个20小时的任务时,我必须将它们分解成多个集合,并在网格中显示它们。我必须将它们分开,因为不同的任务可能会被分配给不同的用户,并且可能有不同的注释等等

    Cheers

    虽然不是最漂亮的(通过增加小时数在日期时间上做一个棘轮循环有点不雅观),但您的函数可以调整为提供一个可枚举的每天工作小时数(或更常用的工作小时数),如下所示:

    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;
        }
    }
    

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

    public static double[]GetWorkHours(日期时间开始、日期时间结束、时间跨度工作开始时间、时间跨度工作结束时间)
    {
    IList结果=新列表();
    如果(开始>结束)
    {
    抛出新ArgumentException(“开始日期晚于结束日期”);
    }
    DateTime currentDate=开始日期;
    
    while(currentDate=workEndTime | | realEndTime)实体框架在这里是如何涉及的?我怀疑您在EF中是否会找到关于这方面的任何特殊内容。很抱歉,我们稍后将添加更多与实体相关的内容,但没有添加,并且忘记删除标记。数组len稍后会提供使用实体插入的记录总数。“给定多个时间跨度"-听起来你并不想提供时间跨度,你想提供两个日期/时间。然后,对于每个日期,返回当天的工作小时数。对吗?开始/结束时间对其他日期有何影响?听起来不应该-不在开始/结束时间内的每一天实际上都是午夜到午夜?有在这里重新回答这个问题:但公认的解决方案与OP已经发布的非常相似,因此,这适用于我正在编写的一个简单任务调度应用程序。用户可以添加长度超过8小时的任务,例如20小时。任务可以在一天中的任何时间开始。我以8小时为单位显示它们->查看问题以获取更新另外,如果你只是计算整小时,为什么要使用
    double
    来计算小时数呢?我想说
    int
    更合适,如果从周五早上开始,周一晚上,这将返回[8,0,0,8](因为周六和周日)。随着应用程序的进展,它将考虑到。5个小时的块,但到目前为止,它保持简单,因此使用了双重。感谢此解决方案,我本可以删除0,这将给我[8,8]。添加任务的迭代已忽略周末,因此应该可以:)非常感谢,这实际上给出了我想要的结果。GetStartTimeForDay和GetEndTimeForDay是缺少的部分。
    double[] hoursPerDay = getWorkingHrsPerDay(beginDate, endDate).ToArray();
    
        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;
        }