我有一个List ActionSchedule
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,
}
示例列表:
登录9:00 暂停9:02 10:00恢复 关闭15:00
登录17:00 暂停18:00 18:30恢复 关闭21:00
登录22:00 关闭06:00(第二天)
我需要从此列表中获取以Mode =登录广告开头的操作以Mode = Close和模式登录的开始(TimeSpan)&gt; time.now和模式开始关闭&lt;现在是时候了。
如果datetime现在是10:00,它会给我gr1列表
如果datetime现在是14:00,它会给我gr1列表
如果datetime现在是16:00,它会给我gr2 list导致gr1在15:00结束
如果datetime现在是20:00,它会给我gr2
如果datetime现在是23:00,它会给我gr3
如果datetime现在是05:00,它会给我gr3
如果datetime现在是07:00它会给我gr1因为gr3在06:00结束
感谢您的帮助。
答案 0 :(得分:1)
您的要求不清楚,但我会尝试推断。
你有List<ActionSchedule>
。
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) }
};
您需要List<List<ActionSchedule>>
(或类似List<ActionScheduleCollection>
之类的内容),以便您可以拥有&#34;群组&#34;,让我们将其命名为actionLists
。它将包含您的所有ActionSchedule
,分为列表(&#34;群组&#34;),以Login
ActionSchedule开头,以Close
结尾。实施是微不足道的:
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);
}
你想要当前&#34;活跃&#34;组(DateTime.Now介于&#34;活动&#34;组的登录和关闭时间),或者将是&#34;活跃&#34;下。
如果datetime现在是14:00,它会给我gr1列表
如果datetime现在是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);
}
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}");
}