2017-06-02 78 views
1

我想将正确的小时数绑定到正确的工作时间段。工作周从周一到周日。根据当天的工作时间不同的价格。根据当天的时间完成的工作价格称为期间。我们使用24小时时间格式。根据工作日和小时+假日添加工作时间以更正价格类别

实施例:

  • PERIOD1:周一 - 周五,00:00 - 07:00
  • PERIOD2:周一 - 周五,07:00 - 20:00
  • Period3:周一 - 周五, 20:00 - 22:00
  • Period4:周一 - 周五,22:00 - 23:59(午夜)
  • Period5:星期六 - 星期日,00:00 - 07:00
  • Period6:星期六 - 太阳,07:00 - 22:00
  • Period7:星期六 - 星期日,22:00 - 23:59(午夜)
  • Period8:假日00:00 - 23:59

周期是这样表示:

public class Period 
{ 
    public Period() 
    { 
    } 

    public string Name { get; set; } 
    public int Days { get; set; } 
    public bool Holiday { get; set; } 
    public TimeSpan Start { get; set; } 
    public TimeSpan End { get; set; } 
} 

天为int,但值将来自该枚举:

[Flags] 
public enum Workweek 
{ 
    Sunday = 1, 
    Monday = 2, 
    Tuesday = 4, 
    Wednesday = 8, 
    Thursday = 16, 
    Friday = 32, 
    Saturday = 64 
} 

当周期Days属性为62这意味着I期有效期为星期一至星期五,星期几为:65期间为星期六至星期日。当Days是:6期间是从星期一到星期二。

Holiday为真时表示该期间仅在休假日有效。节假日覆盖正常的一天或周末。

工作班次是这样表示:

public class Work 
{ 
    public Work() 
    { 
    } 

    public string Name { get; set; } 
    public DateTime Start { get; set; } 
    public DateTime End { get; set; } 
} 

假设我有一个List<Work>List<Period>我如何可以将绑定在工作时间以正确的期间?每个期间都有不同的定价。

例子:

案例1:如果你之间在周一工作班次:15:00和23:00,那么工作班次将是这样的:

  • PERIOD2:5小时
  • Period3:2小时
  • Period4:1小时

情况1。1:如果特定的星期一,节日,那么这将是:

  • Period8 8小时

案例2:如果不是工作在周一开始于20:00,结束于04: 00第二天结果将是:

  • Period3:1小时
  • Period4:1小时
  • PERIOD1:四小时

案例2.2:如果星期一是假日,这将是:

  • Period8:四小时
  • PERIOD1:四小时

假期日子如List<DateTime>

我怎样才能匹配正确的时间段?

我试过到目前为止:

Work work = new Work() 
{ 
    Name = Demo, 
    Star = new DateTime(2017,05,02,15,00,00); 
    End = new DateTime(2017,05,02,23,00,00); 
}; 

List<Period> periods = new List<Period>(); 

foreach (var period in periods) 
{ 
    Workweek shiftDay = (Workweek)Enum.Parse(typeof(Workweek), work.Start.DayOfWeek, true); // i think this is wrong, because in the case where the end date is in the next day 


    Workweek periodDay = (Workweek)period.Days; 

    if ((shiftDay & periodDay) == shiftDay) 
    { 
     // the work matches the period 
    } 

} 

我想我应该使用foreach循环,并通过每个第二起始日期和结束日期之间,并检查如果第二期天相匹配。

事情是这样的:

public static IEnumerable<DateTime> EachSecond(this Work work) 
    { 
     DateTime currentSecond = new DateTime(work.Start.Year, work.Start.Month, work.Start.Day, work.Start.Hour, work.Start.Minute, work.Start.Second, work.Start.Millisecond); 
     while (currentSecond <= wor.kEnd) 
     { 
      yield return currentSecond; 
      currentSecond = currentSecond.AddSeconds(1); 
     } 
    } 

    Work work = new Work() 
    { 
     Name = Demo, 
     Star = new DateTime(2017,05,02,15,00,00); 
     End = new DateTime(2017,05,02,23,00,00); 
    }; 

    List<Period> periods = new List<Period>(); 

    foreach (var second in work.EachSecond()) 
    { 
      Workweek shiftSecond = (Workweek)Enum.Parse(typeof(Workweek), second.DayOfWeek, true); 

      foreach (var period in periods) 
      { 
       Workweek periodDay = (Workweek)period.Days; 

       if ((shiftSecond & periodDay) == shiftSecond) 
       { 

       } 
      } 
    } 
+2

你需要显示至少一些试图解决这个问题,计算器不是代码编写售后服务所有。 – Evk

+0

@Evk:更新了问题 – user2818430

+0

我认为这个方法并不是太过于简单。从我的头顶我看到两件事:1.你真的需要重复几秒钟?这段时间是基于分钟的,所以我也会在匹配过程中使用分钟。 2.您也可以查看[DateTime.CompareTo](https://msdn.microsoft.com/de-de/library/system.datetime.compare(v = vs.110).aspx),然后使用保存持续时间在这两者之间可以节省循环,但可能需要更多的代码。目前我无法生成示例:/ –

回答

1

工作例如:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Diagnostics; 

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     var periods = new List<Period> { 
      new Period("1", Days.Workdays, TimeSpan.FromHours(0), TimeSpan.FromHours(7)), 
      new Period("2", Days.Workdays, TimeSpan.FromHours(7), TimeSpan.FromHours(20)), 
      new Period("3", Days.Workdays, TimeSpan.FromHours(20), TimeSpan.FromHours(22)), 
      new Period("4", Days.Workdays, TimeSpan.FromHours(22), TimeSpan.FromHours(24)), 
      new Period("5", Days.Weekend, TimeSpan.FromHours(0), TimeSpan.FromHours(7)), 
      new Period("6", Days.Weekend, TimeSpan.FromHours(7), TimeSpan.FromHours(22)), 
      new Period("7", Days.Weekend, TimeSpan.FromHours(22), TimeSpan.FromHours(24)), 
      new Period("8", Days.Holiday, TimeSpan.FromHours(0), TimeSpan.FromHours(24)), 
     }; 
     var holidays = new List<DateTime> { 
      new DateTime(2017, 1, 1), 
      new DateTime(2017, 1, 3), 
      new DateTime(2017, 1, 6), 
     }; 

     var sc = new ShiftCalculator(periods, holidays); 

     var shiftperiods = sc.GetShiftPeriods(new DateTime(2016, 12, 31, 22, 00, 00), new DateTime(2017, 01, 07, 08, 00, 00)).ToList(); 

     foreach (var sp in shiftperiods) 
     { 
      Console.WriteLine("{0} - {1} - {2} - {3:00.00}h", sp.Period.Name, sp.Period.Days, sp.Start, sp.Duration.TotalHours); 
     } 

    } 
} 

[Flags] 
enum Days : byte 
{ 
    Sunday = 1, 
    Monday = 2, 
    Tuesday = 4, 
    Wednesday = 8, 
    Thursday = 16, 
    Friday = 32, 
    Saturday = 64, 
    Holiday = 128, 

    Workdays = Monday | Tuesday | Wednesday | Thursday | Friday, 
    Weekend = Saturday | Sunday, 
} 

[DebuggerDisplay("{Name}: {Days} ({Start}-{End})")] 
class Period 
{ 
    public Period(string name, Days days, TimeSpan start, TimeSpan end) 
    { 
     if (days.HasFlag(Days.Holiday) && days != Days.Holiday) 
      throw new ArgumentException("days"); 

     if (start > end) 
      throw new ArgumentException("end"); 

     Name = name; 
     Days = days; 
     Start = start; 
     End = end; 
    } 

    public string Name { get; private set; } 
    public Days Days { get; private set; } 
    public TimeSpan Start { get; private set; } 
    public TimeSpan End { get; private set; } 
} 

class ShiftPeriod 
{ 
    public Period Period { get; set; } 
    public DateTime Start { get; set; } 
    public TimeSpan Duration { get; set; } 
} 

class ShiftCalculator 
{ 
    private readonly List<Period> _periods; 
    private readonly List<DateTime> _holidays; 

    public ShiftCalculator(IEnumerable<Period> periods, IEnumerable<DateTime> holidays) 
    { 
     _periods = periods.ToList(); 
     _holidays = holidays.Select(e => e.Date).ToList(); 
    } 

    public IEnumerable<ShiftPeriod> GetShiftPeriods(DateTime start, DateTime end) 
    { 
     if (start > end) throw new ArgumentException("end"); 

     var current = start; 

     while (current < end) 
     { 
      var period = GetPeriodByDateTime(current); 

      var next = current.Date + period.End; 

      if (next > end) 
      { 
       next = end; 
      } 

      yield return new ShiftPeriod 
      { 
       Period = period, 
       Start = current, 
       Duration = next - current, 
      }; 

      current = next; 
     } 

    } 

    private Days GetDayFromDateTime(DateTime datetime) 
    { 
     Days day; 
     if (_holidays.Contains(datetime.Date)) 
     { 
      day = Days.Holiday; 
     } 
     else 
     { 
      switch (datetime.DayOfWeek) 
      { 
       case DayOfWeek.Sunday: 
       day = Days.Sunday; 
       break; 
       case DayOfWeek.Monday: 
       day = Days.Monday; 
       break; 
       case DayOfWeek.Tuesday: 
       day = Days.Tuesday; 
       break; 
       case DayOfWeek.Wednesday: 
       day = Days.Wednesday; 
       break; 
       case DayOfWeek.Thursday: 
       day = Days.Thursday; 
       break; 
       case DayOfWeek.Friday: 
       day = Days.Friday; 
       break; 
       case DayOfWeek.Saturday: 
       day = Days.Saturday; 
       break; 
       default: 
       throw new InvalidOperationException(); 
      } 
     } 
     return day; 
    } 

    private Period GetPeriodByDateTime(DateTime datetime) 
    { 
     var day = GetDayFromDateTime(datetime); 
     var timeOfDay = datetime.TimeOfDay; 
     var period = _periods.Where(
      e => e.Days.HasFlag(day) && e.Start <= timeOfDay && e.End > timeOfDay) 
      .FirstOrDefault(); 
     if (period == null) 
     { 
      throw new InvalidOperationException(); 
     } 
     return period; 
    } 
} 

.net fiddle

生成的输出

 
7 - Weekend - 12/31/2016 10:00:00 PM - 02.00h 
8 - Holiday - 1/1/2017 12:00:00 AM - 24.00h 
1 - Workdays - 1/2/2017 12:00:00 AM - 07.00h 
2 - Workdays - 1/2/2017 7:00:00 AM - 13.00h 
3 - Workdays - 1/2/2017 8:00:00 PM - 02.00h 
4 - Workdays - 1/2/2017 10:00:00 PM - 02.00h 
8 - Holiday - 1/3/2017 12:00:00 AM - 24.00h 
1 - Workdays - 1/4/2017 12:00:00 AM - 07.00h 
2 - Workdays - 1/4/2017 7:00:00 AM - 13.00h 
3 - Workdays - 1/4/2017 8:00:00 PM - 02.00h 
4 - Workdays - 1/4/2017 10:00:00 PM - 02.00h 
1 - Workdays - 1/5/2017 12:00:00 AM - 07.00h 
2 - Workdays - 1/5/2017 7:00:00 AM - 13.00h 
3 - Workdays - 1/5/2017 8:00:00 PM - 02.00h 
4 - Workdays - 1/5/2017 10:00:00 PM - 02.00h 
8 - Holiday - 1/6/2017 12:00:00 AM - 24.00h 
5 - Weekend - 1/7/2017 12:00:00 AM - 07.00h 
6 - Weekend - 1/7/2017 7:00:00 AM - 01.00h 
+0

如果我们添加一个跨越午夜的时间段,我们如何才能使其工作如此:'新时期(“100”,Days.Workdays,TimeSpan.FromHours(22),TimeSpan .FromHours(07)'注意开始时间是22:00,结束时间是07:00。 – user2818430

1

尝试这样的事情。我不知道为什么当你使用标准的DayOfWeek时你需要定制的工作周。把我按照你的要求。

using System.Collections.ObjectModel; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication57 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

     } 

    } 
    public class Period 
    { 
     public static List<Period> periods = new List<Period>() { 
      new Period() { Name = "Period1", Days = new Workweek[] { Workweek.Monday, Workweek.Tuesday, Workweek.Wednesday, Workweek.Thursday, Workweek.Friday}, Holiday = false, Start = new TimeSpan(0,0,0), End = new TimeSpan(7,0,0)}, 
      new Period() { Name = "Period2", Days = new Workweek[] { Workweek.Monday, Workweek.Tuesday, Workweek.Wednesday, Workweek.Thursday, Workweek.Friday}, Holiday = false, Start = new TimeSpan(7,0,0), End = new TimeSpan(20,0,0)}, 
      new Period() { Name = "Period3", Days = new Workweek[] { Workweek.Monday, Workweek.Tuesday, Workweek.Wednesday, Workweek.Thursday, Workweek.Friday}, Holiday = false, Start = new TimeSpan(20,0,0), End = new TimeSpan(22,0,0)}, 
      new Period() { Name = "Period4", Days = new Workweek[] { Workweek.Monday, Workweek.Tuesday, Workweek.Wednesday, Workweek.Thursday, Workweek.Friday}, Holiday = false, Start = new TimeSpan(22,0,0), End = new TimeSpan(24,0,0)}, 
      new Period() { Name = "Period5", Days = new Workweek[] { Workweek.Saturday, Workweek.Sunday}, Holiday = false, Start = new TimeSpan(0,0,0), End = new TimeSpan(7,0,0)}, 
      new Period() { Name = "Period6", Days = new Workweek[] { Workweek.Saturday, Workweek.Sunday}, Holiday = false, Start = new TimeSpan(7,0,0), End = new TimeSpan(22,0,0)}, 
      new Period() { Name = "Period7", Days = new Workweek[] { Workweek.Saturday, Workweek.Sunday}, Holiday = false, Start = new TimeSpan(22,0,0), End = new TimeSpan(24,0,0)}, 
      new Period() { Name = "Period8", Days = null, Holiday = true, Start = new TimeSpan(0,0,0), End = new TimeSpan(24,0,0)}, 
     }; 

     public string Name { get; set; } 
     public Workweek[] Days { get; set; } 
     public bool Holiday { get; set; } 
     public TimeSpan Start { get; set; } 
     public TimeSpan End { get; set; } 

     public static string GetName(DateTime startTime, DateTime endTime, Boolean holiday) 
     { 
      string name = ""; 

      if (holiday) 
      { 
       name = "Period8"; 
      } 
      else 
      { 

       foreach (Period period in periods) 
       { 
        Boolean dayMatch = period.Days.Select(x => x == (Workweek)(2^(int)startTime.DayOfWeek)).Any(); 
        if (dayMatch) 
        { 
         if ((startTime.TimeOfDay > period.Start) && (endTime.TimeOfDay < period.End)) 
         { 
          name = period.Name; 
          break; 
         } 
        } 

       } 
      } 

      return name; 
     } 
    } 
    public enum Workweek 
    { 
     Sunday = 1, 
     Monday = 2, 
     Tuesday = 4, 
     Wednesday = 8, 
     Thursday = 16, 
     Friday = 32, 
     Saturday = 64 
    } 
    public class Work 
    { 

     public string Name { get; set; } 
     public DateTime Start { get; set; } 
     public DateTime End { get; set; } 
    } 


} 
+0

dayMatch我错过了一个等号。应该是“x => x ==” – jdweng

相关问题