根据 DateTime.Now 和预定义时间比较检测工作班次。 C#
Detecting work shift based on DateTime.Now and predefined hours comparison. c#
我希望我的程序在新工作班次开始时重置统计数据。
我的轮班时间预定义为:
- 白班 4:00 - 16:25 周一至周四(4:00 - 15:55 周五至周日)
- 夜班 16:25 - 4:00 周一至周四(15:55 - 4:00 周五至周日)
这就是我目前正在做的,它有效,但我不知道如何在上午结束班次时进行时间比较,所以现在它在班次结束时工作设置为 23:59:59,但当我将其更改为凌晨 4 点时,它倒在了它的屁股上...
DateTime d1 = new DateTime(2020, 01, 01, 16, 25, 00); //Mon-Thur shift change
DateTime d2 = new DateTime(2020, 01, 01, 15, 55, 00); //Fri-Sun shift change
DateTime d3 = new DateTime(2020, 01, 01, 23, 59, 59); //Evening shift end
DateTime d4 = new DateTime(2020, 01, 01, 04, 00, 00); //Morning shift start
DateTime d5 = DateTime.Now;
if (d5.DayOfWeek == DayOfWeek.Monday || d5.DayOfWeek == DayOfWeek.Tuesday || d5.DayOfWeek == DayOfWeek.Wednesday || d5.DayOfWeek == DayOfWeek.Thursday)
{
if (d5.TimeOfDay >= d4.TimeOfDay && d5.TimeOfDay < d1.TimeOfDay)
{
dayShift = true;
eveShift = false;
}
}
if (d5.DayOfWeek == DayOfWeek.Friday || d5.DayOfWeek == DayOfWeek.Saturday || d5.DayOfWeek == DayOfWeek.Sunday)
{
if (d5.TimeOfDay >= d4.TimeOfDay && d5.TimeOfDay < d2.TimeOfDay)
{
dayShift = true;
eveShift = false;
}
}
if (d5.DayOfWeek == DayOfWeek.Monday || d5.DayOfWeek == DayOfWeek.Tuesday || d5.DayOfWeek == DayOfWeek.Wednesday || d5.DayOfWeek == DayOfWeek.Thursday)
{
if (d5.TimeOfDay >= d1.TimeOfDay && d5.TimeOfDay < d3.TimeOfDay)
{
dayShift = false;
eveShift = true;
}
}
if (d5.DayOfWeek == DayOfWeek.Friday || d5.DayOfWeek == DayOfWeek.Saturday || d5.DayOfWeek == DayOfWeek.Sunday)
{
if (d5.TimeOfDay >= d2.TimeOfDay && d5.TimeOfDay < d3.TimeOfDay)
{
dayShift = false;
eveShift = true;
}
}
我该怎么做才能比较 TimeOfDay 和 AM 时间?
我想检查时间是否在 d1 和 d4 之间。有什么想法吗?
我会改变这里的方法。而不是一组时间,我会定义什么构成了对象中的 'shift' 定义,有这些对象的列表,然后遍历它们并针对它们测试当前的 date/time ...
这最终比我乍一看要复杂得多,因为 2:33AM 星期二 实际上 会在 星期一结束 我猜是晚班...
但我会这样做:
public enum ShiftType
{
Unknown, //default..
Day,
Night
}
public class DailyShiftDetail
{
public IEnumerable<DayOfWeek> DaysOfWeek {get;set;}
public DateTime Start { get; set; }
public DateTime End { get; set; }
public ShiftType Type { get; set; }
}
public class ShiftCheck
{
//define shifts on each day. This data could come from a database or something
private static IEnumerable<DailyShiftDetail> shifts = new List<DailyShiftDetail>
{
new DailyShiftDetail
{
//Mon-Thu daytime shift
DaysOfWeek=new[]
{
DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday
},
Start = new DateTime(2000,1,1,4,0,0), //4AM
End = new DateTime(2000,1,1,16,25,0), //4:25PM
Type=ShiftType.Day
},
new DailyShiftDetail
{
//Fri-Sun daytime shift
DaysOfWeek=new[]
{
DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday
},
Start = new DateTime(2000,1,1,04,0,0), //4AM
End = new DateTime(2000,1,1,15,55,0), //3:55PM
Type=ShiftType.Day
},
new DailyShiftDetail
{
//Mon-Thu Evening shift
DaysOfWeek=new[]
{
DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday
},
Start = new DateTime(2000,1,1,16,25,0),
End = new DateTime(2000,1,1,4,0,0),
Type=ShiftType.Night
},
new DailyShiftDetail
{
//Fri-Sun Evening shift
DaysOfWeek=new[]
{
DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday
},
Start = new DateTime(2000,1,1,15,55,0),
End = new DateTime(2000,1,1,4,0,0),
Type=ShiftType.Night
}
};
public static ShiftType GetShiftTypeForDate(DateTime testDate)
{
//you could probably do this all with a .Where() or
//.FirstOrDefault, but the logic in the LINQ stuff
//would end up being a bit painful. This is probably
//a little less efficient but will perform fine,
//and the logic is easier to follow.
DailyShiftDetail matchingShift = null;
foreach(var testShift in shifts)
{
var shiftStart = testShift.Start.TimeOfDay;
var shiftEnd = testShift.End.TimeOfDay;
//check logic differently for evening shifts,
//as not only are the times going over midnight,
//but in fact 2AM on a tuesday is a *Monday EVENING* shift...
//So we need to check the following days too..
if (shiftStart > shiftEnd)
{
//if the testing time is earlier than the end of shift, then it's between
//midnight and the shift time.
if (testDate.TimeOfDay < shiftEnd)
{
//we need to work out what day this 'shift' would have started on...
//this will not be the DayOfWeek of the passed-in time, but the day before...
//just cast to int, subtract one, account for rollover and cast back to DayOfWeek...
int dayBefore = (int)testDate.DayOfWeek - 1;
if (dayBefore < 0)
{
dayBefore = 6;
}
var dayOfWeekBefore = (DayOfWeek)dayBefore;
//now we've worked out the theoretical day the shift starts, we can test that.
if (testShift.DaysOfWeek.Contains(dayOfWeekBefore))
{
matchingShift = testShift;
}
}
//otherwise, if the test time of day is after the start of the shift then we can check the
//current day and if that matches the shift we can return it too
else if (
testDate.TimeOfDay > shiftStart
&& testShift.DaysOfWeek.Contains(testDate.DayOfWeek))
{
matchingShift = testShift;
}
}
else
{
//daytime shift.
//simple logic. Day matches and test time between start and end.
//Assume end time is EXCLUSIVE as otherwise 4:00AM EXACTLY is in two different shifts..
if (
testShift.DaysOfWeek.Contains(testDate.DayOfWeek)
&& testShift.Start.TimeOfDay <= testDate.TimeOfDay
&& testShift.End.TimeOfDay > testDate.TimeOfDay
)
{
matchingShift = testShift;
}
}
//if we found a match, stop looping through shifts.
if (matchingShift != null)
{
break;
}
}
if (matchingShift == null)
{
//couldn't work it out, so return this...
return ShiftType.Unknown;
}
//found a shift record, return its type.
return matchingShift.Type;
}
}
要使用,您可以测试任何 date/time 并返回 'Day' 或 'Night'
//Today, tuesday 22nd @ 5:55pm.. would be an evening shift?
var nightShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 22, 17, 55, 0));
//is ShiftType.Night
//today, tuesday 22nd @ 6AM... would be a day shift?
var dayShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 22, 6, 0, 0));
//is ShiftType.Day
//a friday at 15:57 would be a night shift
var friNightShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 18, 15, 57, 0));
//is ShiftType.Night
//a Wednesday at 15:57 would be a DAY shift though
var wedDayShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 16, 15, 57, 0));
//is ShiftType.Day.
我只进行了简短的测试,因此可能在某处存在一些逻辑错误,但应该很容易调试....
我希望我的程序在新工作班次开始时重置统计数据。 我的轮班时间预定义为:
- 白班 4:00 - 16:25 周一至周四(4:00 - 15:55 周五至周日)
- 夜班 16:25 - 4:00 周一至周四(15:55 - 4:00 周五至周日)
这就是我目前正在做的,它有效,但我不知道如何在上午结束班次时进行时间比较,所以现在它在班次结束时工作设置为 23:59:59,但当我将其更改为凌晨 4 点时,它倒在了它的屁股上...
DateTime d1 = new DateTime(2020, 01, 01, 16, 25, 00); //Mon-Thur shift change
DateTime d2 = new DateTime(2020, 01, 01, 15, 55, 00); //Fri-Sun shift change
DateTime d3 = new DateTime(2020, 01, 01, 23, 59, 59); //Evening shift end
DateTime d4 = new DateTime(2020, 01, 01, 04, 00, 00); //Morning shift start
DateTime d5 = DateTime.Now;
if (d5.DayOfWeek == DayOfWeek.Monday || d5.DayOfWeek == DayOfWeek.Tuesday || d5.DayOfWeek == DayOfWeek.Wednesday || d5.DayOfWeek == DayOfWeek.Thursday)
{
if (d5.TimeOfDay >= d4.TimeOfDay && d5.TimeOfDay < d1.TimeOfDay)
{
dayShift = true;
eveShift = false;
}
}
if (d5.DayOfWeek == DayOfWeek.Friday || d5.DayOfWeek == DayOfWeek.Saturday || d5.DayOfWeek == DayOfWeek.Sunday)
{
if (d5.TimeOfDay >= d4.TimeOfDay && d5.TimeOfDay < d2.TimeOfDay)
{
dayShift = true;
eveShift = false;
}
}
if (d5.DayOfWeek == DayOfWeek.Monday || d5.DayOfWeek == DayOfWeek.Tuesday || d5.DayOfWeek == DayOfWeek.Wednesday || d5.DayOfWeek == DayOfWeek.Thursday)
{
if (d5.TimeOfDay >= d1.TimeOfDay && d5.TimeOfDay < d3.TimeOfDay)
{
dayShift = false;
eveShift = true;
}
}
if (d5.DayOfWeek == DayOfWeek.Friday || d5.DayOfWeek == DayOfWeek.Saturday || d5.DayOfWeek == DayOfWeek.Sunday)
{
if (d5.TimeOfDay >= d2.TimeOfDay && d5.TimeOfDay < d3.TimeOfDay)
{
dayShift = false;
eveShift = true;
}
}
我该怎么做才能比较 TimeOfDay 和 AM 时间?
我想检查时间是否在 d1 和 d4 之间。有什么想法吗?
我会改变这里的方法。而不是一组时间,我会定义什么构成了对象中的 'shift' 定义,有这些对象的列表,然后遍历它们并针对它们测试当前的 date/time ...
这最终比我乍一看要复杂得多,因为 2:33AM 星期二 实际上 会在 星期一结束 我猜是晚班...
但我会这样做:
public enum ShiftType
{
Unknown, //default..
Day,
Night
}
public class DailyShiftDetail
{
public IEnumerable<DayOfWeek> DaysOfWeek {get;set;}
public DateTime Start { get; set; }
public DateTime End { get; set; }
public ShiftType Type { get; set; }
}
public class ShiftCheck
{
//define shifts on each day. This data could come from a database or something
private static IEnumerable<DailyShiftDetail> shifts = new List<DailyShiftDetail>
{
new DailyShiftDetail
{
//Mon-Thu daytime shift
DaysOfWeek=new[]
{
DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday
},
Start = new DateTime(2000,1,1,4,0,0), //4AM
End = new DateTime(2000,1,1,16,25,0), //4:25PM
Type=ShiftType.Day
},
new DailyShiftDetail
{
//Fri-Sun daytime shift
DaysOfWeek=new[]
{
DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday
},
Start = new DateTime(2000,1,1,04,0,0), //4AM
End = new DateTime(2000,1,1,15,55,0), //3:55PM
Type=ShiftType.Day
},
new DailyShiftDetail
{
//Mon-Thu Evening shift
DaysOfWeek=new[]
{
DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday
},
Start = new DateTime(2000,1,1,16,25,0),
End = new DateTime(2000,1,1,4,0,0),
Type=ShiftType.Night
},
new DailyShiftDetail
{
//Fri-Sun Evening shift
DaysOfWeek=new[]
{
DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday
},
Start = new DateTime(2000,1,1,15,55,0),
End = new DateTime(2000,1,1,4,0,0),
Type=ShiftType.Night
}
};
public static ShiftType GetShiftTypeForDate(DateTime testDate)
{
//you could probably do this all with a .Where() or
//.FirstOrDefault, but the logic in the LINQ stuff
//would end up being a bit painful. This is probably
//a little less efficient but will perform fine,
//and the logic is easier to follow.
DailyShiftDetail matchingShift = null;
foreach(var testShift in shifts)
{
var shiftStart = testShift.Start.TimeOfDay;
var shiftEnd = testShift.End.TimeOfDay;
//check logic differently for evening shifts,
//as not only are the times going over midnight,
//but in fact 2AM on a tuesday is a *Monday EVENING* shift...
//So we need to check the following days too..
if (shiftStart > shiftEnd)
{
//if the testing time is earlier than the end of shift, then it's between
//midnight and the shift time.
if (testDate.TimeOfDay < shiftEnd)
{
//we need to work out what day this 'shift' would have started on...
//this will not be the DayOfWeek of the passed-in time, but the day before...
//just cast to int, subtract one, account for rollover and cast back to DayOfWeek...
int dayBefore = (int)testDate.DayOfWeek - 1;
if (dayBefore < 0)
{
dayBefore = 6;
}
var dayOfWeekBefore = (DayOfWeek)dayBefore;
//now we've worked out the theoretical day the shift starts, we can test that.
if (testShift.DaysOfWeek.Contains(dayOfWeekBefore))
{
matchingShift = testShift;
}
}
//otherwise, if the test time of day is after the start of the shift then we can check the
//current day and if that matches the shift we can return it too
else if (
testDate.TimeOfDay > shiftStart
&& testShift.DaysOfWeek.Contains(testDate.DayOfWeek))
{
matchingShift = testShift;
}
}
else
{
//daytime shift.
//simple logic. Day matches and test time between start and end.
//Assume end time is EXCLUSIVE as otherwise 4:00AM EXACTLY is in two different shifts..
if (
testShift.DaysOfWeek.Contains(testDate.DayOfWeek)
&& testShift.Start.TimeOfDay <= testDate.TimeOfDay
&& testShift.End.TimeOfDay > testDate.TimeOfDay
)
{
matchingShift = testShift;
}
}
//if we found a match, stop looping through shifts.
if (matchingShift != null)
{
break;
}
}
if (matchingShift == null)
{
//couldn't work it out, so return this...
return ShiftType.Unknown;
}
//found a shift record, return its type.
return matchingShift.Type;
}
}
要使用,您可以测试任何 date/time 并返回 'Day' 或 'Night'
//Today, tuesday 22nd @ 5:55pm.. would be an evening shift?
var nightShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 22, 17, 55, 0));
//is ShiftType.Night
//today, tuesday 22nd @ 6AM... would be a day shift?
var dayShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 22, 6, 0, 0));
//is ShiftType.Day
//a friday at 15:57 would be a night shift
var friNightShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 18, 15, 57, 0));
//is ShiftType.Night
//a Wednesday at 15:57 would be a DAY shift though
var wedDayShift = ShiftCheck.GetShiftTypeForDate(
new DateTime(2020, 9, 16, 15, 57, 0));
//is ShiftType.Day.
我只进行了简短的测试,因此可能在某处存在一些逻辑错误,但应该很容易调试....