Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 按操作分组并获取rightdatime_C#_Linq_Datetime_Grouping - Fatal编程技术网

C# 按操作分组并获取rightdatime

C# 按操作分组并获取rightdatime,c#,linq,datetime,grouping,C#,Linq,Datetime,Grouping,我有一份行动计划表 public class ActionSchedule { public TaskJob Mode {get;set} public TimeSpan Start {get;set} public DateTime ConvertToDatime(bool updatenextday = false) { DateTime result = DateTime.Today.Add(Start); if (upd

我有一份行动计划表

public class ActionSchedule
{
    public TaskJob Mode {get;set}
    public TimeSpan Start {get;set}

    public DateTime ConvertToDatime(bool updatenextday = false)
    {
        DateTime result = DateTime.Today.Add(Start);

        if (updatenextday)
        {
            if (Start.Hours < dateTimeNow.Hour || (Start.Hours == dateTimeNow.Hour && Start.Minutes <= dateTimeNow.Minute))
                result = result.AddDays(1);
        }

        return result;
    }

} 

public enum TaskJob
    {
        Pause,
        Resume,
        Login,
        Close,
    }
公共类操作计划
{
公共任务作业模式{get;set}
公共时间跨度开始{get;set}
public DateTime ConvertToDatime(bool updatenextday=false)
{
DateTime结果=DateTime.Today.Add(开始);
如果(updatenextday)
{
如果(Start.Hours
如果datetime现在是10:00,它会给我gr1列表

如果datetime现在是14:00,它会给我gr1列表

如果datetime现在是16:00,它会给我gr2列表,因为gr1在15:00结束

如果datetime现在是20:00,它将给我gr2

如果datetime现在是23:00,它会给我gr3

如果datetime现在是05:00,它将给我gr3

如果datetime现在是07:00,它将给我gr1,因为gr3在06:00结束


谢谢您的帮助。

您的要求不清楚,但我将尝试推断

上下文 您有一个
列表

要求 您需要当前“活动”组(DateTime.Now介于“活动”组的登录时间和关闭时间之间),或下一个将“活动”的组

如果datetime现在是14:00,它会给我gr1列表

如果datetime now是16:00,它将给我gr2列表,因为gr1在15:00结束(注意:即使gr2在17:00开始)

解决方案 这比我想象的要复杂得多!而且有这样一个不方便的
ActionSchedule
结构

基本上,我们进行两步验证以获得当前组。 首先,我们天真地检查是否存在登录时间小于当前时间、关闭时间大于当前时间的组。 如果没有,我们将遍历这些组,将每个组与下一个组进行比较,并找到关闭时间小于当前时间的组,以及下一个组的登录时间大于当前时间的组

这有点像文字沙拉,下面是一些代码:

private static List<ActionSchedule> GetCurrentGroup(List<List<ActionSchedule>> actionLists, TimeSpan now)
{
    var currentGroup = actionLists.SingleOrDefault(actionList => IsActive(actionList, now));

    if (currentGroup == null)
    {
        // Comparing each list with the next to see where 'now' fits for the 'next active group'
        // We assume lists are already ordered by their start time, and that their start/close times
        // don't overlap
        for (int i = 0; i < actionLists.Count; i++)
        {
            // index of the next list; if it's out of bounds, we reset to the first list, index 0
            int j = i + 1;
            if (j >= actionLists.Count)
                j = 0;

            var nextList = actionLists[j];

            var closeFirst = actionLists[i].Single(action => action.Mode == TaskJob.Close).Start;
            var loginLast = nextList.Single(action => action.Mode == TaskJob.Login).Start;

            if (TimeBetween(now, closeFirst, loginLast))
            {
                currentGroup = nextList;
                break;
            }
        }
    }

    return currentGroup;
}

private static bool IsActive(List<ActionSchedule> actionList, TimeSpan now)
{
    var login = actionList.Single(action => action.Mode == TaskJob.Login).Start;
    var close = actionList.Single(action => action.Mode == TaskJob.Close).Start;
    return TimeBetween(now, login, close);
}

private static bool TimeBetween(TimeSpan now, TimeSpan start, TimeSpan end)
{
    if (start < end)
        return start <= now && now <= end;
    return !(end < now && now < start);
}
私有静态列表GetCurrentGroup(列出ActionList,TimeSpan now)
{
var currentGroup=actionList.SingleOrDefault(actionList=>IsActive(actionList,now));
如果(currentGroup==null)
{
//将每个列表与下一个列表进行比较,查看“现在”适合“下一个活动组”的位置
//我们假设列表已经按开始时间排序,并且它们的开始/结束时间
//不要重叠
for(int i=0;i=actionlist.Count)
j=0;
var nextList=actionlist[j];
var closeFirst=actionlist[i].Single(action=>action.Mode==TaskJob.Close).Start;
var loginLast=nextList.Single(action=>action.Mode==TaskJob.Login).Start;
if(TimeBetween(现在、closeFirst、loginLast))
{
currentGroup=nextList;
打破
}
}
}
返回电流组;
}
私有静态bool IsActive(列出actionList,TimeSpan now)
{
var login=actionList.Single(action=>action.Mode==TaskJob.login);
var close=actionList.Single(action=>action.Mode==TaskJob.close);
返回时间间隔(现在,登录,关闭);
}
私有静态bool TimeBetween(TimeSpan now、TimeSpan start、TimeSpan end)
{
如果(开始<结束)

返回开始它看起来不像一个组。一个组(即gr1)可以有更多的项目吗,比如3个不同的登录、关闭时间?它是一个“排序”列表我添加了标记gr#只是为了更好地理解它,结果将出现在第一个示例列表中:登录9:00暂停9:02恢复10:00关闭15:00是否应该
ActionSchedule
具有另一个属性,如
ActionId
,它显示了它们属于哪个操作?您应该正确执行该操作?为什么您认为ActionSchedule需要ActionId如果具有执行相同作业的TaskJob(枚举)。
var actionLists = new List<List<ActionSchedule>>();
List<ActionSchedule> actionList = null;
foreach (var action in actions)
{
    if (action.Mode == TaskJob.Login)
    {
        actionList = new List<ActionSchedule>();
        actionLists.Add(actionList);
    }

    actionList.Add(action);
}
private static List<ActionSchedule> GetCurrentGroup(List<List<ActionSchedule>> actionLists, TimeSpan now)
{
    var currentGroup = actionLists.SingleOrDefault(actionList => IsActive(actionList, now));

    if (currentGroup == null)
    {
        // Comparing each list with the next to see where 'now' fits for the 'next active group'
        // We assume lists are already ordered by their start time, and that their start/close times
        // don't overlap
        for (int i = 0; i < actionLists.Count; i++)
        {
            // index of the next list; if it's out of bounds, we reset to the first list, index 0
            int j = i + 1;
            if (j >= actionLists.Count)
                j = 0;

            var nextList = actionLists[j];

            var closeFirst = actionLists[i].Single(action => action.Mode == TaskJob.Close).Start;
            var loginLast = nextList.Single(action => action.Mode == TaskJob.Login).Start;

            if (TimeBetween(now, closeFirst, loginLast))
            {
                currentGroup = nextList;
                break;
            }
        }
    }

    return currentGroup;
}

private static bool IsActive(List<ActionSchedule> actionList, TimeSpan now)
{
    var login = actionList.Single(action => action.Mode == TaskJob.Login).Start;
    var close = actionList.Single(action => action.Mode == TaskJob.Close).Start;
    return TimeBetween(now, login, close);
}

private static bool TimeBetween(TimeSpan now, TimeSpan start, TimeSpan end)
{
    if (start < end)
        return start <= now && now <= end;
    return !(end < now && now < start);
}
static void Main(string[] args)
{
    var actions = new List<ActionSchedule>
    {
        new ActionSchedule { Mode = TaskJob.Login, Start = new TimeSpan(9,0,0) },
        new ActionSchedule { Mode = TaskJob.Pause, Start = new TimeSpan(9,2,0) },
        new ActionSchedule { Mode = TaskJob.Resume, Start = new TimeSpan(10,0,0) },
        new ActionSchedule { Mode = TaskJob.Close, Start = new TimeSpan(15,0,0) },
        new ActionSchedule { Mode = TaskJob.Login, Start = new TimeSpan(17,0,0) },
        new ActionSchedule { Mode = TaskJob.Pause, Start = new TimeSpan(18,0,0) },
        new ActionSchedule { Mode = TaskJob.Resume, Start = new TimeSpan(18,30,0) },
        new ActionSchedule { Mode = TaskJob.Close, Start = new TimeSpan(21,0,0) },
        new ActionSchedule { Mode = TaskJob.Login, Start = new TimeSpan(22,0,0) },
        new ActionSchedule { Mode = TaskJob.Close, Start = new TimeSpan(6,0,0) }
    };

    var actionLists = new List<List<ActionSchedule>>();
    List<ActionSchedule> actionList = null;
    foreach (var action in actions)
    {
        if (action.Mode == TaskJob.Login)
        {
            actionList = new List<ActionSchedule>();
            actionLists.Add(actionList);
        }

        actionList.Add(action);
    }

    Console.WriteLine("Time is 10:00:00");
    PrintGroup(GetCurrentGroup(actionLists, new TimeSpan(10, 0, 0)));

    Console.WriteLine("Time is 14:00:00");
    PrintGroup(GetCurrentGroup(actionLists, new TimeSpan(14, 0, 0)));

    Console.WriteLine("Time is 16:00:00");
    PrintGroup(GetCurrentGroup(actionLists, new TimeSpan(16, 0, 0)));

    Console.WriteLine("Time is 20:00:00");
    PrintGroup(GetCurrentGroup(actionLists, new TimeSpan(20, 0, 0)));

    Console.WriteLine("Time is 23:00:00");
    PrintGroup(GetCurrentGroup(actionLists, new TimeSpan(23, 0, 0)));

    Console.WriteLine("Time is 05:00:00");
    PrintGroup(GetCurrentGroup(actionLists, new TimeSpan(5, 0, 0)));

    Console.WriteLine("Time is 07:00:00");
    PrintGroup(GetCurrentGroup(actionLists, new TimeSpan(7, 0, 0)));

    Console.ReadLine();
}

private static void PrintGroup(List<ActionSchedule> group)
{
    Console.WriteLine($"Login: {group.Single(a => a.Mode == TaskJob.Login).Start}, Closing: {group.Single(a => a.Mode == TaskJob.Close).Start}");
}