[英]Date time range of shift in a day split into intervals of 10 minutes C#
I am wondering if anyone can help me, I have a collection of start times and end times for a work shift of a day.我想知道是否有人可以帮助我,我收集了一天工作班次的开始时间和结束时间。 the hours can be spread across the day.
时间可以分布在一天中。 I am trying group by the hour in day (like 0, 1, 2...23, 24) and show that hour in intervals of 10 minutes or worked or not worked.
我正在尝试按小时分组(如 0、1、2...23、24),并以 10 分钟的间隔显示该小时,或者工作或不工作。 So, I would like to get the end result like below:
所以,我想得到如下的最终结果:
I want to able distinguish between worked and not on a hourly basis, the input provides the worked but I have calculate the not worked, I created a method for handling if a time falls outside a 10 minute interval it will set to the nearest one.我希望能够区分工作和不是每小时,输入提供工作但我计算了不工作,我创建了一种处理方法,如果时间超出 10 分钟间隔,它将设置为最接近的时间间隔。 Method called DoRounding:
名为 DoRounding 的方法:
Example:例子:
9 am => 0 - 10 Worked
10 - 20 Not Worked
20 - 30 Worked
30 - 40 Worked
40 - 50 Worked
50 - 60 Worked
The time that fails out of the period can be be handled like so过期的时间可以这样处理
private static int DoRounding(DateTime date)
{
if (Enumerable.Range(0, 10).Contains(date.Minute))
return 0;
if (Enumerable.Range(10, 20).Contains(date.Minute))
return 20;
if (Enumerable.Range(20, 30).Contains(date.Minute))
return 30;
if (Enumerable.Range(30, 40).Contains(date.Minute))
return 40;
if (Enumerable.Range(40, 50).Contains(date.Minute))
return 50;
return 60;
}
My method to explode the workblock (I was trying to break down the work period into hours here so I could add the missing parts in another method)我分解工作块的方法(我试图在这里将工作时间分解为几个小时,以便我可以用另一种方法添加缺失的部分)
public static IEnumerable<Tuple<int, DateTime>> CalculateIntervals(WorkPeriod workBlock)
{
yield return new Tuple<int, DateTime>(workBlock.StartTime.Hour, workBlock.StartTime);
var dateTime = new DateTime(workBlock.StartTime.Year, workBlock.StartTime.Month, workBlock.StartTime.Day, workBlock.StartTime.Hour, workBlock.StartTime.Minute, 0, workBlock.StartTime.Kind).AddHours(1);
while (dateTime < workBlock.EndTime)
{
yield return new Tuple<int, DateTime>(dateTime.Hour, dateTime);
dateTime = dateTime.AddHours(1);
}
yield return new Tuple<int, DateTime>(workBlock.EndTime.Hour, workBlock.EndTime);
}
My attempt at grouping (I want to group into the time slots here to the hour and the intervals such as 1 pm, 0 - 10 minutes and mark it as worked but if an interval was missing from here add it as not worked)我的分组尝试(我想将这里的时间段分组到小时和时间间隔,例如下午 1 点、0 - 10 分钟,并将其标记为有效,但如果此处缺少间隔,则将其添加为无效)
public static void WorkingHourIntervalStrings(List<WorkPeriod> WorkingHours)
{
var output = new List<Tuple<int, DateTime>>();
foreach (var result in WorkingHours.Select(CalculateIntervals))
output.AddRange(result);
output = output.OrderBy(x => x.Item2).ToList();
var test = output.GroupBy(
p => p.Item1,
p => p.Item2.Minute,
(key, g) => new { Worked = key, Minute = g.ToList() });
}
Class班级
public class WorkPeriod
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
Calling打电话
var input = new List<WorkPeriod>
{
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 9, 40, 56), EndTime = new DateTime(2020, 5, 25, 14, 22, 12) },
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 9, 50, 56), EndTime = new DateTime(2020, 5, 25, 14, 59, 12) },
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 13, 40, 56), EndTime = new DateTime(2020, 5, 25, 18, 22, 12) },
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 19, 40, 56), EndTime = new DateTime(2020, 5, 25, 23, 22, 12) }
};
TimeIntervals.WorkingHourIntervalStrings(input);
Possible output structure:可能的输出结构:
public class Interval
{
public Interval() => Contents = new List<Contents>();
public int Hour { get; set; }
public List<Contents> Contents { get; set; }
}
public class Contents
{
public bool Worked { get; set; }
public int Start { get; set; }
public int End { get; set; }
}
Based on your above explanations I would do the following:根据您的上述解释,我将执行以下操作:
public class Interval
{
public Interval() => Contents = new List<Contents>();
public int Hour { get; set; }
public List<Contents> Contents { get; set; }
}
public class Contents
{
public bool Worked { get; set; }
public int Start { get; set; }
//public int End { get; set; }
public int End => Start + 10;
}
public class WorkPeriod
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
Look at the Contents class.查看 Contents 类。 The
End
property is autocalculated from the Start
one. End
属性是从Start
。 Then I would create the following Calculator
class:然后我将创建以下
Calculator
类:
public class Calculator
{
public bool[] WorkedIntervals = new bool[24 * 6];
private void SetWork(int Hour, int Min)
{
int pos = Hour * 6 + Min / 10;
WorkedIntervals[pos] = true;
}
private void UpdateIntervals(WorkPeriod period)
{
var cur = period.StartTime;
while (cur < period.EndTime)
{
SetWork(cur.Hour, cur.Minute);
cur = cur.AddMinutes(10);
}
}
private void UpdateIntervals(List<WorkPeriod> periods)
{
foreach (var l in periods)
UpdateIntervals(l);
}
public IEnumerable<Interval> CalcIntervals(List<WorkPeriod> periods)
{
var minTime = (from p in periods
select p.StartTime).Min();
var maxTime = (from p in periods
select p.EndTime).Max();
UpdateIntervals(periods);
for(int h=minTime.Hour; h<=maxTime.Hour; ++h)
{
int pos = h * 6;
var intrvl = new Interval() { Hour = h };
for (int m=0; m<=5; m++)
{
if (WorkedIntervals[pos + m])
intrvl.Contents.Add(new Contents() { Start = m * 10, Worked = true });
else
intrvl.Contents.Add(new Contents() { Start = m * 10, Worked = false });
}
yield return intrvl;
}
}
}
The idea is that you have to flatten all your time intervals to an array of 144 boolean values (24*6) that represents if each of this 10 minute time interval has been worked or not.这个想法是,您必须将所有时间间隔展平为 144 个布尔值 (24*6) 的数组,该数组表示这 10 分钟时间间隔中的每一个是否都有效。 eg.
例如。 if the 7th index of the array is true then it means that at Hour 1 (hour 0 is in indexes 0-5) the 10-20 min interval has been worked.
如果数组的第 7 个索引为真,则意味着在第 1 小时(第 0 小时在索引 0-5 中),10-20 分钟的时间间隔已经工作。
Then, on your main function you do the following.然后,在您的主要功能上,您执行以下操作。
var input = new List<WorkPeriod>
{
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 9, 40, 56), EndTime = new DateTime(2020, 5, 25, 14, 22, 12) },
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 9, 50, 56), EndTime = new DateTime(2020, 5, 25, 14, 59, 12) },
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 13, 40, 56), EndTime = new DateTime(2020, 5, 25, 18, 22, 12) },
new WorkPeriod { StartTime = new DateTime(2020, 5, 25, 19, 40, 56), EndTime = new DateTime(2020, 5, 25, 23, 22, 12) }
};
Calculator ints = new Calculator();
var res = ints.CalcIntervals(input).ToList();
The res
list should contain the hour-intervals from the minimum StartTime
to the maximum EndTime
with their respected sub-lists. res
列表应包含从最小StartTime
到最大EndTime
的小时间隔及其受尊重的子列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.