C# 我怎样才能知道最后一班是什么时候开始的?(按24小时计划)

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

如果不同的团队每天24小时在不同的班次上工作(比如一组工作3个8小时班次,另一组工作2个12小时班次,最后一组工作2个10小时班次,4小时无人值守),给定一个时间点,返回最近开始的班次的最直接方法是什么

例如,我有一个8小时
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的情况下他们可以重叠)。谢谢,我喜欢它,但它给出了错误的班次!第二次比较应为