c# - 如何使用 Lambda 表达式在同一天的日期时间记录中查找时差
问题描述
这是一个表格,其中包含用户活动的多个事件以及执行活动的日期和时间。我如何找到每个配对活动之间的时间差。
Activity | Datetime
IN |2019-11-12 06:45:14.1234042
OUT |2019-11-12 09:20:14.2291323
IN |2019-11-12 10:35:14.4541043
OUT |2019-11-12 19:36:14.3431042
IN |2019-11-13 09:33:14.6541045
OUT |2019-11-13 18:35:14.3441042
IN |2019-11-14 06:32:14.2361042
OUT |2019-11-14 12:23:14.2345044
IN |2019-11-14 16:24:14.3791034
IN |2019-11-15 11:10:14.2245446
OUT |2019-11-15 19:44:14.5349504
需要注意的是,在 2019 年 11 月 14 日的第二个 In 条目没有 Out 条目的情况下,可能会缺少缩减动作。在这种情况下,In 条目被视为无效。
输出看起来像
2019-11-12 | 02:35
2019-11-12 | 09:01
2019-11-13 | 09:02
2019-11-14 | 05:51
2019-11-15 | 04:01
2019-11-16 | 08:34
解决方案
我可能在这个 LOL 上矫枉过正了!但是我开始写了,所以我不妨把它贴出来。顺便说一句,我是在 Notepad++ 中编写的,并没有尝试在 Visual Studio 中运行它,所以我不能保证它会立即运行。
一般的想法是您必须加载数据,然后您必须根据您需要的特定规则配对您的组。然后,您可以使用 Linq 获取 IN 和 OUT 对之间的时间跨度。
namespace SODemo
{
class Program
{
static void Main(string[] args)
{
//Load the data
List<ActivityTime> activities = ReadInActivityTimes();
//Trying to do a lambda on the activities list would be out of scope
// for a normal use of a Linq query. Because each item requires knowledge of the
// next item in the list. So there needs to be a step where the related pairs are grouped.
List<ActivityTimePair> pairs = CreatePairs(activities);
//Now we can run a Linq query.
List<TimeSpan> output = pairs
.Where(p => p.HasBoth)
.Select(p => p.GetTimeSpan().Value)
.ToList();
output.ForEach(ts =>
{
Console.WriteLine(ts.ToString());
});
}
static List<ActivityTime> ReadInActivityTimes()
{
return new List<ActivityTime>() {
new ActivityTime() { Activity = "IN", TimeStamp = DateTime.Parse("2019-11-12 06:45:14.1234042" },
new ActivityTime() { Activity = "OUT", TimeStamp = DateTime.Parse("2019-11-12 09:20:14.2291323" },
new ActivityTime() { Activity = "IN", TimeStamp = DateTime.Parse("2019-11-12 10:35:14.4541043" },
new ActivityTime() { Activity = "OUT", TimeStamp = DateTime.Parse("2019-11-12 19:36:14.3431042" },
new ActivityTime() { Activity = "IN", TimeStamp = DateTime.Parse("2019-11-13 09:33:14.6541045" },
new ActivityTime() { Activity = "OUT", TimeStamp = DateTime.Parse("2019-11-13 18:35:14.3441042" },
new ActivityTime() { Activity = "IN", TimeStamp = DateTime.Parse("2019-11-14 06:32:14.2361042" },
new ActivityTime() { Activity = "OUT", TimeStamp = DateTime.Parse("2019-11-14 12:23:14.2345044" },
new ActivityTime() { Activity = "IN", TimeStamp = DateTime.Parse("2019-11-14 16:24:14.3791034" },
new ActivityTime() { Activity = "IN", TimeStamp = DateTime.Parse("2019-11-15 11:10:14.2245446" },
new ActivityTime() { Activity = "OUT", TimeStamp = DateTime.Parse("2019-11-15 19:44:14.5349504" }
};
}
static List<ActivityTimePair> CreatePairs(List<ActivityTime> activities)
{
List<ActivityTimePair> pairs = new List<ActivityTimePair>();
for (int i = 0; i < activities.Count; i++)
{
if (pairs.Count == 0) //first one
{
pairs.Add(new ActivityTimePair());
}
if (activities[i].Activity == "IN")
{
//If the last pair has an OUT, then we need a new pair
if (pairs.Last().OUT != null)
{
pairs.Add(new ActivityTimePair() { IN = activities[i]});
}
//handle case where there are 2 IN's in a row
else if (pairs.Last().IN != null)
{
//Means there is 2 INs in a row
pairs.Add(new ActivityTimePair() { IN = activities[i]});
}
else
{
pairs.Last().IN = activities[i];
}
}
if (activities[i].Activity == "OUT")
{
//If the last pair has an OUT, there are 2 OUT's in a row
if (pairs.Last().OUT != null)
{
//Means there is 2 OUTs in a row
pairs.Add(new ActivityTimePair() { OUT = activities[i]});
}
else if (pairs.Last().IN != null)
{
pairs.Last().OUT = activities[i];
}
//handle case where we need a new pair
else
{
pairs.Add(new ActivityTimePair() { OUT = activities[i]});
}
}
}
return pairs;
}
}
class ActivityTime
{
public string Activity { get; set; }
public DateTime TimeStamp { get; set; }
}
class ActivityTimePair
{
public ActivityTime IN { get; set; }
public ActivityTime OUT { get; set; }
public bool HasBoth
{
get
{
return IN != null && OUT != null;
}
}
public TimeSpan? GetTimeSpan()
{
if (HasBoth)
{
return OUT.TimeStamp.Subtract(IN.TimeStamp);
}
else
{
return null;
}
}
}
}
推荐阅读
- c# - 在 ASP.NET Core 2.2 和 ASP 之间共享 Cookie 身份验证。没有 Microsoft.Identity 的 NET MVC 5 (.NET Framework 4.6.1)
- django - 使用 Django 模型中的字段对数据进行计算
- junit - 如何在扩展中使用 TempDir
- css - .SCSS 文件中的数学计算 Angular CLI 不起作用
- php - 如何在同一服务器上的 Web 应用程序(核心 PHP)和另一个 Web 应用程序(Laravel)之间共享会话?
- python-2.7 - 将运行时数据存储到 CSV 文件
- azure-active-directory - 针对 Azure AD 进行身份验证的问题
- javascript - 将图像从视频 JS 保存到画布
- javascript - 拖动一个元素但放下一组其他元素
- django - 在推荐系统中将 sqlite 表读取为 csv 文件时出现问题