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}");
}