繁体   English   中英

从有效日期开始计算小时数

[英]Counting hours from a valid date

我有一个小问题,因为我并不总是了解如何使用当天的课程,例如,我希望列表中的时间从该日期重新计算当天的时间,但是如果我有新的时间,则进行转换从新的时间开始计算。 如果我只有一次,它对我来说很好,但如果我有两次, foreach循环会计算我一天的两次。

这是我的代码:

  public TimeSpan GetHoursForDay(DateTime day) {
         TimeSpan time = TimeSpan.Zero;

         foreach (var times in shouldWorkTime)
                {
                    if (times.Valid_from > day) //here's the real problem for me, do i want the hours to count from that date, for example: for 1.1.2020 it doesn't need to take hours from 1.12.2019
                        continue;
                    if (day.DayOfWeek == DayOfWeek.Monday)
                    {
                        time += times.ShouldWorkMonday;
                    }
                    if (day.DayOfWeek == DayOfWeek.Tuesday)
                    {
                        time += times.ShouldWorkTuesday;
                    }
                    if (day.DayOfWeek == DayOfWeek.Wednesday)
                    {
                        time += times.ShouldWorkWednesday;
                    }
                    if (day.DayOfWeek == DayOfWeek.Thursday)
                    {
                        time += times.ShouldWorkThursday;
                    }
                    if (day.DayOfWeek == DayOfWeek.Friday)
                    {
                        time += times.ShouldWorkFriday;
                    }
                    if (day.DayOfWeek == DayOfWeek.Saturday)
                    {
                        time += times.ShouldWorkSaturday;
                    }
                    if (day.DayOfWeek == DayOfWeek.Sunday)
                    {
                        time += times.ShouldWorkSunday;
                    }
                }
                return time;
            }
    }

这些是我在列表中得到的值:

var shouldWorkTime = new List<ShouldWorkTime>
            {
             new ShouldWorkTime
             {
            Valid_from = new DateTime(2019, 12, 01, 0, 0, 0), 
            ShouldWorkMonday = new TimeSpan(8,0,0),
            ShouldWorkTuesday= new TimeSpan(7,0,0),
            ShouldWorkWednesday= new TimeSpan(6,0,0),
            ShouldWorkThursday= new TimeSpan(5,0,0),
            ShouldWorkFriday= new TimeSpan(8,0,0),
            ShouldWorkSaturday = new TimeSpan(0,0,0),
            ShouldWorkSunday = new TimeSpan(0,0,0)
            },
            new ShouldWorkTime
            {
            Valid_from = new DateTime(2020, 01, 01, 0, 0, 0), 
            ShouldWorkMonday = new TimeSpan(4,0,0),
            ShouldWorkTuesday= new TimeSpan(3,0,0),
            ShouldWorkWednesday= new TimeSpan(6,0,0),
            ShouldWorkThursday= new TimeSpan(5,0,0),
            ShouldWorkFriday= new TimeSpan(9,0,0),
            ShouldWorkSaturday = new TimeSpan(0,0,0),
            ShouldWorkSunday = new TimeSpan(0,0,0)
                }
            };

对于天值,我总是从日历中获取当天的值,所以我想在这种情况下计算 2020 年 1 月 1 日值的天数,这些天数是第二次计数的天数,然后是下降的值在第一次计数。

所以我需要返回工人需要在某一天工作的小时数,但从(Valid_From)的最后一个日期开始有效。

我该如何纠正? 非常感谢大家的帮助

例如:

输入 1.1.2020 输出 = 6,0,0;

输入 1.12.2019 输出 = 0,0,0;

这里是对数据结构的一些修改。
TimeSpan 将使用字典映射到 DayOfWeek,而不是早午餐。 这将消除对 switch-case 或大量 If 的需要。 使用 DayOfWeek 作为字典键确保一天只定义一个 TimeSpan。

public class WorkingTimeScheldure
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public Dictionary<DayOfWeek, TimeSpan> Scheldure { get; set; }
}

这样我就可以使用: Scheldure[test.DayOfWeek]来询问一天的时间跨度

请注意添加了 End 属性。 选择正确的东西可能很有用。
例如:30/01/2020 优于 01/12/2019 和 01/01/2020..
因此,为了采用最新的,我假设列表按开始日期排序并选择最后一个: .Last(x => x.Start <= day)

在线演示

public class Program
{
    static List<ShouldWork> WorkTimeScheldure;
    public static void Main()
    {
        WorkTimeScheldure = new List<ShouldWork>
        {
            new ShouldWork
            {
                Start = new DateTime(2019, 12, 01, 0, 0, 0),
                Scheldure= new Dictionary<DayOfWeek, TimeSpan>()
                {
                    {(DayOfWeek)0,  new TimeSpan(0,0,0)},
                    {(DayOfWeek)1,  new TimeSpan(8,0,0)},
                    {(DayOfWeek)2,  new TimeSpan(7,0,0)},
                    {(DayOfWeek)3,  new TimeSpan(6,0,0)},
                    {(DayOfWeek)4,  new TimeSpan(5,0,0)},
                    {(DayOfWeek)5,  new TimeSpan(8,0,0)},
                    {(DayOfWeek)6,  new TimeSpan(0,0,0)}
                }
            },
            new ShouldWork
            {
                Start = new DateTime(2020, 01, 01, 0, 0, 0),
                Scheldure = new Dictionary<DayOfWeek, TimeSpan>()
                {
                    {(DayOfWeek)0,  new TimeSpan(0,0,0)},
                    {(DayOfWeek)1,  new TimeSpan(4,0,0)},
                    {(DayOfWeek)2,  new TimeSpan(3,0,0)},
                    {(DayOfWeek)3,  new TimeSpan(6,0,0)},
                    {(DayOfWeek)4,  new TimeSpan(5,0,0)},
                    {(DayOfWeek)5,  new TimeSpan(9,0,0)},
                    {(DayOfWeek)6,  new TimeSpan(0,0,0)}
                }
            }
        };

        var testValues = new[] {

            new DateTime(2019, 12, 01, 0, 0, 0),
            new DateTime(2019, 12, 02, 0, 0, 0),
            new DateTime(2019, 12, 03, 0, 0, 0),
            new DateTime(2019, 12, 04, 0, 0, 0),
            new DateTime(2019, 12, 05, 0, 0, 0),
            new DateTime(2019, 12, 06, 0, 0, 0),
            new DateTime(2019, 12, 07, 0, 0, 0),
            new DateTime(2019, 12, 08, 0, 0, 0),

            new DateTime(2020, 01, 01, 0, 0, 0),
            new DateTime(2020, 01, 02, 0, 0, 0),
            new DateTime(2020, 01, 03, 0, 0, 0),
            new DateTime(2020, 01, 05, 0, 0, 0),
            new DateTime(2020, 01, 05, 0, 0, 0),
            new DateTime(2020, 01, 06, 0, 0, 0),
            new DateTime(2020, 01, 07, 0, 0, 0),
            new DateTime(2020, 01, 08, 0, 0, 0),
        };


        foreach (var test in testValues) {

            // Perhaps there is many possible, so I took the Last.
            var workingTime = WorkTimeScheldure.Last(x => x.Start <= day);
            //Please handle the case where there is no matching scheludre for this date.

            var houtToWork = workingTime.Scheldure[day.DayOfWeek].Hours;

            Console.WriteLine(
                $"{day.ToShortDateString()} , it's a {day.DayOfWeek}" +
                $" I have to work {houtToWork} Hour{(houtToWork>1?"s":"")}!"
            );
        }
    }
}

结果 :

12/01/2019 , it's a Sunday I have to work 0 Hour!
12/02/2019 , it's a Monday I have to work 8 Hours!
12/03/2019 , it's a Tuesday I have to work 7 Hours!
12/04/2019 , it's a Wednesday I have to work 6 Hours!
12/05/2019 , it's a Thursday I have to work 5 Hours!
12/06/2019 , it's a Friday I have to work 8 Hours!
12/07/2019 , it's a Saturday I have to work 0 Hour!
12/08/2019 , it's a Sunday I have to work 0 Hour!


01/01/2020 , it's a Wednesday I have to work 6 Hours!
01/02/2020 , it's a Thursday I have to work 5 Hours!
01/03/2020 , it's a Friday I have to work 9 Hours!
01/04/2020 , it's a Saturday I have to work 0 Hour!
01/05/2020 , it's a Sunday I have to work 0 Hour!
01/06/2020 , it's a Monday I have to work 4 Hours!
01/07/2020 , it's a Tuesday I have to work 3 Hours!
01/08/2020 , it's a Wednesday I have to work 6 Hours!

如果day的值足够大,则对于shouldWorkTime所有元素,测试times.Valid_from > dayfalse 这就是为什么time可以增加多次。

如果您只想在Valid_from的第一个/最后一个可接受值上递增一次,则应确保shouldWorkTime按递增/递减顺序排序,并确保递增仅完成一次。

事实上,您不需要 increment 而是返回相应的TimeSpan

public TimeSpan GetHoursForDay(DateTime day) {
    // shouldWorkTime should have been sorted once for all at creation.
    // This code use the first acceptable Valid_from
    // By using OrderByDescending we take the last (in date) entry
    var math = shouldWorkTime
                 .Where(v => day >= v.Valid_from) // We take only valid entry
                 .OrderByDescending(v => v.Valid_from) // We sort only on valid entry
                 .FirstOrDefault(); // we take the last (in date) valid entry

    if (match == null)
        return TimeSpan.Zero;

    switch (day.DayOfWeek)
    {
        case DayOfWeek.Monday:
            return match.ShouldWorkMonday;
        case DayOfWeek.Tuesday:
            return match.ShouldWorkTuesday;
        case DayOfWeek.Wednesday:
            return match.ShouldWorkWednesday;
        case DayOfWeek.Thursday:
            return match.ShouldWorkThursday;
        case DayOfWeek.Friday:
            return match.ShouldWorkFriday;
        case DayOfWeek.Saturday:
            return match.ShouldWorkSaturday;
        case DayOfWeek.Sunday:
            return match.ShouldWorkSunday;
    }
}

编辑

为了避免代码重复, ShouldWorkTime类可以提供一个GetWorkTimeForDayOfWeek

public TimeSpan GetWorkTimeForDayOfWeek(DayOfWeek dayOfWeek) {
  ...
}

您可以查看集合,而不是在七个字段中存储七个值。 我会选择一个Dictionary<DayOfWeek, TimeSpan>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM