C# 我怎样才能知道最后一班是什么时候开始的?(按24小时计划)
如果不同的团队每天24小时在不同的班次上工作(比如一组工作3个8小时班次,另一组工作2个12小时班次,最后一组工作2个10小时班次,4小时无人值守),给定一个时间点,返回最近开始的班次的最直接方法是什么 例如,我有一个8小时C# 我怎样才能知道最后一班是什么时候开始的?(按24小时计划),c#,time,C#,Time,如果不同的团队每天24小时在不同的班次上工作(比如一组工作3个8小时班次,另一组工作2个12小时班次,最后一组工作2个10小时班次,4小时无人值守),给定一个时间点,返回最近开始的班次的最直接方法是什么 例如,我有一个8小时Shifts的列表(开始时间分别是早上6点、下午2点和晚上10点) 我当前的代码可以正常工作(出于我的目的),但并不理想,因为它需要启动时间,并且集合中的转换是有序的 public Shift FindCurrentShift(DateTime startTime, Date
Shift
s的列表(开始时间分别是早上6点、下午2点和晚上10点)
我当前的代码可以正常工作(出于我的目的),但并不理想,因为它需要启动时间,并且集合中的转换是有序的
public Shift FindCurrentShift(DateTime startTime, DateTime endTime, List<Shift> shifts)
{
Shift mostRecentShift = null;
foreach (Shift aShift in shifts) {
DateTime shiftBeginTime = DateTime.Parse(endTime.Date.Add(aShift.BeginTime).ToString());
if (startTime.Date != endTime.Date) {
if (shiftBeginTime.TimeOfDay > startTime.TimeOfDay) {
shiftBeginTime = shiftBeginTime.AddDays(-1);
}
}
//does this shift fall in between start and stop time
if ((startTime < shiftBeginTime && endTime > shiftBeginTime)) {
mostRecentShift = aShift;
}
}
return mostRecentShift;
}
public Shift FindCurrentShift(DateTime startTime、DateTime endTime、List Shift)
{
Shift-mostRecentShift=null;
foreach(轮班制){
DateTime shiftBeginTime=DateTime.Parse(endTime.Date.Add(aShift.BeginTime.ToString());
if(startTime.Date!=endTime.Date){
如果(移位开始时间.TimeOfDay>startTime.TimeOfDay){
shiftBeginTime=shiftBeginTime.AddDays(-1);
}
}
//该班次是否介于开始和停止时间之间
if((开始时间shiftBeginTime)){
mostRecentShift=aShift;
}
}
返回最短的换班时间;
}
考虑到目前的时间,我的班次是什么?做这件事的简单方法是什么?这是一个经典的“找到最大值”问题。仅当
mostRecentShift
为null
或正在检查的班次最近开始时,才应更新该班次。目前,您正在更新它。请尝试使用LINQ:
public Shift FindCurrentShift(DateTime currentDateTime, List<Shift> shifts)
{
DateTime startOfDay = currentDateTime.Date;
// Get most recent shift that started today and has not ended yet
Shift shift =
shifts.Where(s => startOfDay.Add(s.BeginTime) <= currentDateTime
&& startOfDay.Add(s.BeginTime).AddHours(s.LengthHours) <= currentDateTime)
.OrderByDescending(s => s.BeginTime)
.FirstOrDefault();
// If none were found that had a start date today, get the latest shift
// (would be one that started yesterday) as long as its end time today has not passed yet
if (shift == null) {
shift =
shifts.Where(s => startOfDay.AddDays(-1).Add(s.BeginTime).AddHours(s.LengthHours) <= currentDateTime
.OrderByDescending(s => s.BeginTime)
.FirstOrDefault();
}
return shift;
}
public Shift FindCurrentShift(DateTime currentDateTime,List Shift)
{
DateTime startOfDay=currentDateTime.Date;
//获取从今天开始但尚未结束的最新班次
移位=
班次。其中(s=>startOfDay.Add(s.BeginTime)startOfDay.AddDays(-1)。Add(s.BeginTime)。AddHours(s.LengthHours)s.BeginTime)
.FirstOrDefault();
}
返回移位;
}
使用递归和LINQ的解决方案可能如下所示:
/// iterate backwards until a shift is found
/// the recursion stops automatically when the last shift is found
/// AddHour(-1) calculates correctly the date if last shift
/// was "yesterday"
private Shift lastShift(List<Shift> shifts, DateTime startTime)
{
if (shifts.Count > 0)
{
var now = startTime;
var time = new TimeSpan(now.Hour, now.Minute, now.Second);
var shiftRunning = (from s in shifts
let frame = (time - s.BeginTime).Hours
where frame > 0 && frame < s.LengthHours
select s).FirstOrDefault();
if (shiftRunning == null)
{
shiftRunning = lastShift(shifts, startTime.AddHours(-1));
}
return shiftRunning;
}
return null;
}
private Shift findShift(List<Shift> shifts)
{
return lastShift(shifts, DateTime.Now);
}
var shifts = new List<Shift>
{
new Shift { Name = "C", BeginTime = new TimeSpan(22, 00, 00), LengthHours = 8 },
new Shift { Name = "A", BeginTime = new TimeSpan(06, 00, 00), LengthHours = 8 },
new Shift { Name = "B", BeginTime = new TimeSpan(14, 00, 00), LengthHours = 6 },
new Shift { Name = "D", BeginTime = new TimeSpan(11, 00, 00), LengthHours = 8 }
};
var shiftRunning = findShift(shifts);
///向后迭代,直到找到移位
///当找到最后一个班次时,递归自动停止
///AddHour(-1)正确计算上一班的日期
///是“昨天”
私人班次lastShift(列出班次、日期时间开始时间)
{
如果(移位数>0)
{
var now=开始时间;
var time=新的时间跨度(now.Hour,now.Minute,now.Second);
var SHIFTRANNING=(来自轮班中的s
设frame=(time-s.BeginTime).Hours
其中帧>0&&frame
它可以这样使用:
/// iterate backwards until a shift is found
/// the recursion stops automatically when the last shift is found
/// AddHour(-1) calculates correctly the date if last shift
/// was "yesterday"
private Shift lastShift(List<Shift> shifts, DateTime startTime)
{
if (shifts.Count > 0)
{
var now = startTime;
var time = new TimeSpan(now.Hour, now.Minute, now.Second);
var shiftRunning = (from s in shifts
let frame = (time - s.BeginTime).Hours
where frame > 0 && frame < s.LengthHours
select s).FirstOrDefault();
if (shiftRunning == null)
{
shiftRunning = lastShift(shifts, startTime.AddHours(-1));
}
return shiftRunning;
}
return null;
}
private Shift findShift(List<Shift> shifts)
{
return lastShift(shifts, DateTime.Now);
}
var shifts = new List<Shift>
{
new Shift { Name = "C", BeginTime = new TimeSpan(22, 00, 00), LengthHours = 8 },
new Shift { Name = "A", BeginTime = new TimeSpan(06, 00, 00), LengthHours = 8 },
new Shift { Name = "B", BeginTime = new TimeSpan(14, 00, 00), LengthHours = 6 },
new Shift { Name = "D", BeginTime = new TimeSpan(11, 00, 00), LengthHours = 8 }
};
var shiftRunning = findShift(shifts);
var移位=新列表
{
新班次{Name=“C”,开始时间=新的时间跨度(22,00,00),长度小时数=8},
新班次{Name=“A”,开始时间=新时间跨度(06,00,00),长度小时数=8},
新班次{Name=“B”,开始时间=新时间跨度(14,00,00),长度小时数=6},
新班次{Name=“D”,开始时间=新时间跨度(11,00,00),长度小时数=8}
};
var移位耳轴=findShift(移位);
班次顺序不再重要,将始终选择最近的班次(因为使用AddHour(-1)进行了正确的计算)。由于递归,不需要双重检查和复杂的if条件。重叠移位和间隙也因递归而被覆盖。我不是C#guru,我不太了解时间跨度的类型。
如果您只是认为BeginTime是一个介于0到23之间的整数值,那么下面的伪代码可能会起作用:
Shift mostRecentShift = null;
foreach (Shift aShift in shifts)
{
Shift goodShift = null;
if(aShift.BeginTime <= currentTime)
if(aShift.BeginTime + aShift.LengthHours > currentTime)
goodShift = aShift;
else if(24 - aShift.BeginTime < aShift.LengthHours - currentTime)
goodShift = aShift;
if(goodShift != null)
{
if(mostRecentShift == null)
mostRecentShift = goodShift;
else if(mostRecentShift.BeginTime < goodShift.BeginTime)
mostRecentShift = goodShift;
}
}
Shift-mostRecentShift=null;
foreach(轮班制)
{
Shift-goodShift=null;
if(aShift.BeginTime当前时间)
goodShift=aShift;
否则如果(24-aShift.BeginTime
给出一份8小时轮班表(开始时间分别为早上6点、下午2点和晚上10点),
这段代码关注的是0:00~5:59am如果我刚刚更新了mayabelle的答案,则不确定是否符合SO礼仪,但这段代码已经改进,以消除LINQ查询重复并修复一些错误
public Shift FindCurrentShift(DateTime currentDateTime)
{
Shift shift = LastShift(currentDateTime, currentDateTime.Date);
// not in shift that started today? then check yesterday
if (shift == null) {
shift = LastShift(currentDateTime, currentDateTime.Date.AddDays(-1));
}
return shift;
}
private Shift LastShift(DateTime currentDateTime, DateTime startOfDay)
{
return shifts.Where(s => startOfDay.Add(s.BeginTime) <= currentDateTime
&& startOfDay.Add(s.BeginTime).AddHours(s.LengthHours) >= currentDateTime)
.OrderByDescending(s => s.BeginTime)
.FirstOrDefault();
}
//initalize this with shifts
public List<Shift> shifts;
公共移位FindCurrentShift(日期时间currentDateTime)
{
Shift Shift=LastShift(currentDateTime,currentDateTime.Date);
//不是今天开始的班次吗?那昨天再查
if(shift==null){
shift=LastShift(currentDateTime,currentDateTime.Date.AddDays(-1));
}
返回移位;
}
私有移位LastShift(日期时间currentDateTime,日期时间startOfDay)
{
返回班次。其中(s=>startOfDay.Add(s.BeginTime)=currentDateTime)
.OrderByDescending(s=>s.BeginTime)
.FirstOrDefault();
}
//用移位来初始化它
公开名单的变动;
这将返回过去8小时内开始的一个(任意一个)班次。但如果由于某种原因,在过去8小时内没有开始换班,则不会返回最近的换班。如果在过去8小时内开始了多个班次,则它也不一定返回在过去8小时内开始的最后一个班次(即,如果他们重叠,在OP的情况下他们可以重叠)。谢谢,我喜欢它,但它给出了错误的班次!第二次比较应为