C# 用C语言将时间戳列表转换为按小时计算的工作时间#

C# 用C语言将时间戳列表转换为按小时计算的工作时间#,c#,linq,list,datetime,lambda,C#,Linq,List,Datetime,Lambda,我有一个对象列表,详细列出了工人的打卡器,如下所示: Person Time Action Cindy 07:00 clockin Jim 08:12 clockin Cindy 11:15 startlunch Cindy 12:12 endlunch Jim 12:30 startlunch Jim 12:55 endlunch Cindy 15:30 clockout Jim 17:00

我有一个对象列表,详细列出了工人的打卡器,如下所示:

Person  Time     Action
Cindy   07:00    clockin
Jim     08:12    clockin
Cindy   11:15    startlunch
Cindy   12:12    endlunch
Jim     12:30    startlunch
Jim     12:55    endlunch
Cindy   15:30    clockout
Jim     17:00    clockout
Time   Worked
7-8      1
8-9      1.8
9-10     2
10-11    2
11-12    1.25
12-1     1.3
etc.
Person     In      Out
Cindy      07:00  11:15 
Jim        08:22  12:30
Cindy      12:12  15:30
Jim        12:55  17:00
当然,真正的数据是数以百计的人,并且是按部门等分类的

他们希望我制作一份报告,显示一天中每小时的劳动量。最终结果应如下所示:

Person  Time     Action
Cindy   07:00    clockin
Jim     08:12    clockin
Cindy   11:15    startlunch
Cindy   12:12    endlunch
Jim     12:30    startlunch
Jim     12:55    endlunch
Cindy   15:30    clockout
Jim     17:00    clockout
Time   Worked
7-8      1
8-9      1.8
9-10     2
10-11    2
11-12    1.25
12-1     1.3
etc.
Person     In      Out
Cindy      07:00  11:15 
Jim        08:22  12:30
Cindy      12:12  15:30
Jim        12:55  17:00
作为一个中间步骤,我已将一系列穿孔转换为工作记录列表,如下所示:

Person  Time     Action
Cindy   07:00    clockin
Jim     08:12    clockin
Cindy   11:15    startlunch
Cindy   12:12    endlunch
Jim     12:30    startlunch
Jim     12:55    endlunch
Cindy   15:30    clockout
Jim     17:00    clockout
Time   Worked
7-8      1
8-9      1.8
9-10     2
10-11    2
11-12    1.25
12-1     1.3
etc.
Person     In      Out
Cindy      07:00  11:15 
Jim        08:22  12:30
Cindy      12:12  15:30
Jim        12:55  17:00
我在考虑循环所有的时间,并测试每个工作记录,如果它包括在一个给定的小时内的时间,但这似乎很麻烦


是否有一种更优雅的方法可以使用lambda或linq表达式将数据重新组织到最终产品中?它可以从原始数据或interum开始。感谢您研究此难题。

以下是我对LINQ的尝试

我假设您的
工作记录是这样的

公共类工作记录
{
公共只读字符串名称;
公共只读日期时间开始时间;
公共只读日期时间结束时间;
公共工作记录(字符串名称、日期时间开始时间、日期时间结束时间)
{
this.name=名称;
开始时间=开始时间;
结束时间=结束时间;
}
公共工作记录(字符串名称、字符串开始时间、字符串结束时间)
{
this.name=名称;
StarTime=DateTime.ParseExact(StarTime,“HH:mm”,null);
EndTime=DateTime.ParseExact(EndTime,“HH:mm”,null);
}
}
目前尚不清楚它们是否已经过一天的预过滤。我将尝试涵盖这两种情况(但仍然过于简单)

公共类DayStats
{
公共只读整数[]总分钟数=新整数[24];
公共无效添加工作记录(工作记录)
{
//注意:此方法不处理EndTime为第二天时的情况
//处理“中间”时间,他们都满了
对于(int hour=record.StarTime.hour+1;hourstring.Format(“{0}-{1}{2}”,hour,hour+1,totalMinutes));
}
}
公共类TimeCardAggregate
{
专用只读词典_days=新词典();
公共无效添加工作记录(工作记录)
{
//注意:此方法不处理EndTime为第二天时的情况
var date=记录.StarTime.date;
DayStats DayStats;
如果(!\u天.TryGetValue(日期,out dayStats))
{
dayStats=新的dayStats();
_days.Add(日期,dayStats);
}
dayStats.AddWorkRecord(记录);
}
公共列表GetTimecard()
{
return _days.ToList().OrderBy(kv=>kv.Key.ToList();
}
}
DayStats
表示一天的聚合结果<代码>TimeCardAggregate
是几天的结果。在这两个类中,大多数工作都是由helper方法
AddWorkRecord
完成的,您可以从
Aggregate
LINQ方法使用这些方法。了解如何使用它们:

static void Main(字符串[]args)
{
列表记录=新列表
{
新工作记录(“Cindy”,“07:00”,“11:15”),
新工作记录(“吉姆”,“08:22”,“12:30”),
新工作记录(“吉姆”,“12:12”,“15:30”),
新工作记录(“辛迪”,“12:55”,“17:00”)
};
var daysts=records.Aggregate(new daysts(),(ds,wr)=>
{
ds.添加工作记录(wr);
返回ds;
});
WriteLine(dayStats.AsPrettyString());
列表记录fortwodies=新列表();
RecordsFortwodies.AddRange(记录);
//只需复制第二天的数据
RecordsFortwodies.AddRange(records.Select(wr=>new WorkRecord(wr.name,wr.StarTime.AddDays(1),wr.StarTime.AddDays(1)));
var timecard=recordsForTwoDays.Aggregate(新的TimeCardAggregate(),(ds,wr)=>
{
ds.添加工作记录(wr);
返回ds;
});
Console.WriteLine(“\n\n”);
Console.WriteLine(string.Join(“\n------------------\n”,timecard.GetTimecard())。选择(kv=>
{
返回kv.Key.ToShortDateString()+“:\n”+dayStats.AsPrettyString();
})));
}
还要注意的是,
AddWorkRecord
的两个实现都很幼稚,不能处理有人通宵工作并且有记录在几天内生成的情况。但这并不难解决