问题描述
我想知道是否有人可以帮助我,所以我在一天之内收集了工作的开始时间和结束时间。我也想表明相反的情况,所以那天那个人没有工作的时间。我的代码遇到的问题是,它要延续到第二天,而我只想那天。
public class WorkDay
{
public DateTime Day { get; set; }
public List<Worked> WorkingTimes { get; set; }
}
public class Worked
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
static class Program
{
static void Main()
{
var Now = DateTime.Now;
var year = Now.Year;
var month = Now.Month;
var day = Now.Day;
var Day = new WorkDay
{
Day = Now,WorkingTimes = new List<Worked>
{
new Worked { Start = new DateTime(year,month,day,8,30,0),End = new DateTime(year,10,0) },new Worked { Start = new DateTime(year,45,14,0) },50,0).AddHours(10) }
}
};
foreach (var time in Day.WorkingTimes)
Console.WriteLine($"Start {time.Start} " + $"End {time.End}");
Day.WorkingTimes = Day.WorkingTimes.OrderBy(x => x.Start).ToList();
var opposite = Opposite(Day);
foreach (var time in opposite)
Console.WriteLine($"Start {time.Start} " + $"End {time.End}");
Console.WriteLine("Hello World!");
}
public static IEnumerable<Worked> Opposite(WorkDay workDay)
{
var rested = new List<Worked>();
for (var i = workDay.WorkingTimes.Count(); i-- > 0;)
if (i - 1 != -1 && workDay.WorkingTimes[i - 1].End != workDay.WorkingTimes[i].Start)
rested.Add(new Worked { Start = workDay.WorkingTimes[i - 1].End,End = workDay.WorkingTimes[i].Start });
rested = rested.OrderBy(x => x.Start).ToList();
var lastEntry = rested.Last().End.Date;
var lastTime = new DateTime(lastEntry.Year,lastEntry.Month,lastEntry.Day,23,59,59);
if (lastTime > rested.Last().End)
rested.Add(new Worked
{ Start = workDay.WorkingTimes.Last().End,End = lastTime });
return rested;
}
}
所以输出将是: 工作:
Start 21/09/2020 08:30:00 End 21/09/2020 10:30:00
Start 21/09/2020 10:45:00 End 21/09/2020 14:30:00
Start 21/09/2020 14:50:00 End 22/09/2020 00:50:00
相反:
Start 21/09/2020 10:30:00 End 21/09/2020 10:45:00
Start 21/09/2020 14:30:00 End 21/09/2020 14:50:00
Start **22/09/2020** 00:50:00 End 21/09/2020 23:59:59
我要做的是第二天不计算差额。因此,在WorkDay类中有Day,并且所有日期都必须从该天开始。
因此要考虑当天的24小时(无论工作与否),因此,如果他们不工作,则应在相反方法的结果之内进行计算。
解决方法
一个简单的解决方案可能是仅通过rested
和Start
与End
匹配的那些值来过滤Day
结果
// last line of method "Opposite"
return rested.Where(o => o.Start.Date == workDay.Day.Date && o.End.Date == workDay.Day.Date);
,
我将通过对一段时间进行建模来解决此问题,然后提供一种可以Cut
从该时期中抽出一段时间的方法。这样一来,剩下的时间就变得微不足道了。
让我们从Period
类开始:
private sealed class Period : IEquatable<Period>
{
public DateTime StartTime { get; private set; }
public DateTime EndTime { get; private set; }
public Period(DateTime startTime,DateTime endTime)
{
this.StartTime = startTime;
this.EndTime = endTime;
}
public override bool Equals(object obj)
{
if (obj is Period)
return Equals((Period)obj);
return false;
}
public bool Equals(Period obj)
{
if (obj == null)
return false;
if (!EqualityComparer<DateTime>.Default.Equals(this.StartTime,obj.StartTime))
return false;
if (!EqualityComparer<DateTime>.Default.Equals(this.EndTime,obj.EndTime))
return false;
return true;
}
public override int GetHashCode()
{
int hash = 0;
hash ^= EqualityComparer<DateTime>.Default.GetHashCode(this.StartTime);
hash ^= EqualityComparer<DateTime>.Default.GetHashCode(this.EndTime);
return hash;
}
public override string ToString()
{
return String.Format("{{ StartTime = {0},EndTime = {1} }}",this.StartTime,this.EndTime);
}
public IEnumerable<Period> Cut(Period that)
{
if (that.StartTime <= this.StartTime)
{
if (that.EndTime <= this.StartTime)
{
yield return this;
}
else if (that.EndTime < this.EndTime)
{
yield return new Period(that.EndTime,this.EndTime);
}
}
else if (that.StartTime < this.EndTime)
{
if (that.EndTime < this.EndTime)
{
yield return new Period(this.StartTime,that.StartTime);
yield return new Period(that.EndTime,this.EndTime);
}
else
{
yield return new Period(this.StartTime,that.StartTime);
}
}
else
{
yield return this;
}
}
}
现在我们可以这样表示当前的工作时间:
var workingTimes = new[]
{
new Period(new DateTime(year,month,day,8,30,0),new DateTime(year,10,0)),new Period(new DateTime(year,45,14,50,0).AddHours(10)),};
那整天是:
var whole = new Period(now.Date,now.Date.AddDays(1.0));
现在我们可以像这样计算一天的剩余时间:
var result = new [] { whole };
foreach (var d in workingTimes)
{
result = result.SelectMany(r => r.Cut(d)).ToArray();
}
我的最终结果是:
2020/09/21 00:00 - 2020/09/21 08:30 2020/09/21 10:30 - 2020/09/21 10:45 2020/09/21 14:30 - 2020/09/21 14:50