c# - 一天中班次的日期时间范围分为 10 分钟的间隔 C#
问题描述
我想知道是否有人可以帮助我,我收集了一天工作班次的开始时间和结束时间。时间可以分散在一天中。我正在尝试按一天中的小时分组(例如 0、1、2...23、24),并以 10 分钟的间隔显示该小时或工作或不工作。所以,我想得到如下的最终结果:
我希望能够区分工作时间而不是每小时,输入提供工作但我计算了不工作,我创建了一种处理方法,如果时间超出 10 分钟间隔,它将设置为最接近的时间。称为 DoRounding 的方法:
例子:
9 am => 0 - 10 Worked
10 - 20 Not Worked
20 - 30 Worked
30 - 40 Worked
40 - 50 Worked
50 - 60 Worked
超出周期的失败时间可以这样处理
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;
}
我分解工作块的方法(我试图在这里将工作时间分解为几个小时,这样我就可以用另一种方法添加缺失的部分)
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);
}
我的分组尝试(我想将此处的时间段分组为小时和间隔,例如下午 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() });
}
班级
public class WorkPeriod
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
打电话
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);
可能的输出结构:
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 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; }
}
查看 Contents 类。该End
属性是从Start
一个自动计算的。然后我将创建以下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;
}
}
}
这个想法是,您必须将所有时间间隔展平为一个包含 144 个布尔值 (24*6) 的数组,该数组表示这 10 分钟时间间隔中的每一个是否都有效。例如。如果数组的第 7 个索引为真,则意味着在第 1 小时(第 0 小时在索引 0-5 中),10-20 分钟的间隔已经工作。
然后,在您的主要功能上,您执行以下操作。
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();
该列表应包含从最小值到最大值res
的小时间隔及其受尊重的子列表。StartTime
EndTime
推荐阅读
- python - 如何修复 Flask-uwsgi-Nginx 设置中的 Post 请求延迟的 websocket 消息?
- java - 如何向有效负载表达式添加两个路径变量?
- python - Quart Bad Request 语法或不支持的方法
- python-3.x - 将 .py 文件导入另一个脚本以使用其中的变量,其中导入文件由 "if __name__ == '__main__' 运行
- jquery - 获取特定 ID 的值并显示在该行的特定字段上
- javascript - 单击表格行时如何从单元格中获取值
- php - Wordpress 侧边栏子列表中的缩略图
- css - 我想在显示警报时移动 div
- python - 硬编码密码/凭据
- matlab - 在 Matlab 上绘制后更新线不更新