获取当天取件日期时间的相反数
Get opposite of collection date times within the same day
我想知道是否有人可以帮助我,我有一天内工作开始时间和结束时间的集合。我也想显示相反的情况,所以那天那个人没有工作的时间。我的代码存在的问题是它会持续到第二天,而我只想要那一天。
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,month, day,10,30,0) },
new Worked { Start = new DateTime(year,month, day,10,45,0), End = new DateTime(year,month, day,14,30,0) },
new Worked { Start = new DateTime(year,month, day,14,50,0), End = new DateTime(year,month, day,14,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, 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 class 中有日期,所有日期都必须从那天开始。
所以当天的 24 小时被计算在内(工作与否),因此如果他们没有工作,则应在相反方法的结果中考虑。
一个简单的解决方案可能是仅通过 Start
和 End
匹配 Day
的那些值来过滤 rested
结果
// last line of method "Opposite"
return rested.Where(o => o.Start.Date == workDay.Day.Date && o.End.Date == workDay.Day.Date);
我会通过对一段时间建模来解决这个问题,然后提供一种方法可以 Cut
从那段时间中提取出一段时间。然后计算一天剩下的时间就变得微不足道了。
让我们从 Period
class:
开始
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, month, day, 10, 30, 0)),
new Period(new DateTime(year, month, day, 10, 45, 0), new DateTime(year, month, day, 14, 30, 0)),
new Period(new DateTime(year, month, day, 14, 50, 0), new DateTime(year, month, day, 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
我想知道是否有人可以帮助我,我有一天内工作开始时间和结束时间的集合。我也想显示相反的情况,所以那天那个人没有工作的时间。我的代码存在的问题是它会持续到第二天,而我只想要那一天。
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,month, day,10,30,0) },
new Worked { Start = new DateTime(year,month, day,10,45,0), End = new DateTime(year,month, day,14,30,0) },
new Worked { Start = new DateTime(year,month, day,14,50,0), End = new DateTime(year,month, day,14,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, 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 class 中有日期,所有日期都必须从那天开始。
所以当天的 24 小时被计算在内(工作与否),因此如果他们没有工作,则应在相反方法的结果中考虑。
一个简单的解决方案可能是仅通过 Start
和 End
匹配 Day
rested
结果
// last line of method "Opposite"
return rested.Where(o => o.Start.Date == workDay.Day.Date && o.End.Date == workDay.Day.Date);
我会通过对一段时间建模来解决这个问题,然后提供一种方法可以 Cut
从那段时间中提取出一段时间。然后计算一天剩下的时间就变得微不足道了。
让我们从 Period
class:
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, month, day, 10, 30, 0)),
new Period(new DateTime(year, month, day, 10, 45, 0), new DateTime(year, month, day, 14, 30, 0)),
new Period(new DateTime(year, month, day, 14, 50, 0), new DateTime(year, month, day, 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