c# DateTime范围排除特定范围
本文关键字:范围 排除 DateTime | 更新日期: 2023-09-27 18:09:54
我有一个Flags Enum:
[Flags]
public enum WeekDays
{
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64
}
然后是class
public class Task
{
public Task()
{
}
public int Days { get; set; }
public TimeSpan Start { get; set; }
public TimeSpan End { get; set; }
}
假设以下值
Task task = new Task();
task.Days = 7; // from WeekDays enum: 7 = Monday, Tuesday, Wednesday
task.Start = TimeSpan.Parse("00:00"); //midnight
task.End = TimeSpan.Parse("06:00"); //morning 06 AM
和特定范围周期:
DateTime now = DateTime.Now;
DateTime start = now.AddDays(-6);
TimeSpan time = now - start;
double toatlSeconds = time.TotalSeconds; // get total seconds between the start and now datetime range
如何从totalSeconds
中减去任务的totalSeconds
?
所以基本上我想从totalSeconds中排除任务发生的时间段,即每个星期一,星期二,星期三在00:00到06:00之间,即3x6小时= 18小时,即64800秒?
我需要通过对时间范围应用蒙版来做到这一点
这应该是您正在寻找的。我决定重命名你的类,因为在c#中已经有一个Task
类。此外,我使它有工厂方法的创建,因为你想做一些检查的值。还需要注意从DateTime
使用的DayOfWeek
枚举到WeekDays
枚举的映射。基本上,您需要遍历存在于两个DateTime
s之间的每一天,以查看应该从总持续时间中删除多少时间。
public class ScheduledTask
{
private ScheduledTask() { }
public static ScheduledTask CreateTask(TimeSpan start, TimeSpan end, WeekDays days)
{
if (start < TimeSpan.Zero || start >= TimeSpan.FromDays(1))
{
throw new ArgumentOutOfRangeException("start");
}
if (end < TimeSpan.Zero || end >= TimeSpan.FromDays(1))
{
throw new ArgumentOutOfRangeException("end");
}
if (start > end)
{
throw new ArgumentException("End cannot be before Start", "end");
}
if ((int)days < 1 || (int)days >= 128)
{
throw new ArgumentOutOfRangeException("days");
}
return new ScheduledTask { Start = start, End = end, Days = days };
}
public WeekDays Days { get; private set; }
public TimeSpan Start { get; private set; }
public TimeSpan End { get; private set; }
public TimeSpan DifferenceMinusTaskTime(DateTime from, DateTime to)
{
var actualFrom = from;
var actualTo = to;
if (from > to)
{
actualFrom = to;
actualTo = from;
}
TimeSpan duration = TimeSpan.Zero;
DateTime dayStart = actualFrom;
DateTime dayEnd = actualFrom.Date == actualTo.Date
? actualTo
: actualFrom.Date.AddDays(1);
bool endIsNextDay = dayEnd.Date > dayStart.Date;
while (dayStart < actualTo)
{
duration += dayEnd - dayStart;
if (Days.HasFlag(mapping[dayStart.DayOfWeek])
&& dayStart.TimeOfDay < End
&& (dayEnd.TimeOfDay > Start || endIsNextDay))
{
if (dayStart.TimeOfDay < Start)
{
if (dayEnd.TimeOfDay > End || endIsNextDay)
{
duration -= End - Start;
}
else
{
duration -= dayEnd.TimeOfDay - Start;
}
}
else
{
if (dayEnd.TimeOfDay > End || endIsNextDay)
{
duration -= End - dayStart.TimeOfDay;
}
else
{
duration -= dayEnd - dayStart;
}
}
}
dayStart = dayEnd;
dayEnd = dayStart.Date == actualTo.Date
? actualTo
: dayStart.Date.AddDays(1);
endIsNextDay = dayEnd.Date > dayStart.Date;
}
return from > to ? TimeSpan.Zero - duration : duration;
}
private Dictionary<DayOfWeek, WeekDays> mapping =
new Dictionary<DayOfWeek, WeekDays>
{
{ DayOfWeek.Monday, WeekDays.Monday },
{ DayOfWeek.Tuesday, WeekDays.Tuesday },
{ DayOfWeek.Wednesday, WeekDays.Wednesday },
{ DayOfWeek.Thursday, WeekDays.Thursday },
{ DayOfWeek.Friday, WeekDays.Friday },
{ DayOfWeek.Saturday, WeekDays.Saturday },
{ DayOfWeek.Sunday, WeekDays.Sunday }
};
}
加上上面的
var task = ScheduledTask.CreateTask(
TimeSpan.FromHours(2),
TimeSpan.FromHours(8),
WeekDays.Monday | WeekDays.Tuesday | WeekDays.Wednesday);
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24),
new DateTime(2015, 8, 27))); // 2 days 6 hours
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 27),
new DateTime(2015, 8, 24))); // -2 days 6 hours
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 28),
new DateTime(2015, 8, 29))); // 1 day
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24),
new DateTime(2015, 8, 24, 10, 0, 0))); // 4 hours
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24),
new DateTime(2015, 8, 24, 4, 0, 0))); // 2 hours
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24, 4, 0, 0),
new DateTime(2015, 8, 24, 6, 0, 0))); // 0 hours
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24, 4, 0, 0),
new DateTime(2015, 8, 24, 10, 0, 0))); // 2 hours
Console.WriteLine(
task.DifferenceMinusTaskTime(
new DateTime(2015, 8, 24, 10, 0, 0),
new DateTime(2015, 8, 24, 14, 0, 0))); // 4 hours
将输出
2.06:00:00
-2.06:00:00
1.00:00:00
04:00:00
02:00:00
就是
02:00:00
04:00:00