在忽略工作日和节假日的时间跨度之后查找日期时间



我在向开始日期添加持续时间时尝试计算完成日期,但跳过周末和节假日:

DateTime start = DateTime.Now;
TimeSpan duration = TimeSpan.FromHours(100);
List<DateTime> = //List of holidays
DateTime end = ?

例如,如果是星期五晚上 11 点,我加上 2 小时,它将在周一早上 1 点结束。

有没有一种巧妙的方法可以做到这一点?

我有一个临时修复程序,它将时间增加一个小时并检查星期几,但它效率非常低。

原始想法(未经测试(:

public static DateTime calEndDate(DateTime start, TimeSpan duration, List<DateTime> holidays)
{
var startDay = start.Day;
var i = 0;
var t = 0;
while (TimeSpan.FromHours(t) < duration)
{
var date = start.Add(TimeSpan.FromHours(i));
if (date.DayOfWeek.ToString() != "Saturday" && date.DayOfWeek.ToString() != "Sunday") //and something like !holidays.contains(start)
{
t++;
}
i++;
}
return start.Add(TimeSpan.FromHours(t));
}
}

但是,在一个 asp.net 页面加载中,需要针对不同的开始日期/持续时间运行 100 多次。我不知道如何对其进行基准测试,但这似乎不是一个优雅的解决方案?

这是我尝试的算法。

我在手机上,我会弄错的,但你应该看到逻辑......

var end = start;
var timeToMidnight = start.Date.AddDays(1) -start;
if ( duration < timeToMidnight ) return start + duration; 
end = endMoment + timeToMidnight;
duration = duration - timeToMidnight;
//Helper method
bool IsLeisure(Datetime dt) => (dt.DayOfWeek == DayOfWeek.Saturday) || (dt.DayOfWeek == DayOfWeek.Sunday) || holidays.Any( h => h.Date == dt.Date);
//We're at the first tick of the new day. Let's move to a work day, if needed.
while(IsLeisure(end)) { end = end.AddDays(1); };
//Now let's process full days of 'duration'
while(duration >= TimeSpan.FromDays(1) ) {
end = end.AddDays(1);
if(!IsLeisure(end)) duration = duration - TimeSpan.FromDays(1);
}
//Finally, add the reminder
end = end + duration;

注意:您尚未指定开始时刻是周末或节假日的逻辑。

是的,有:

DateTime currentT = DateTime.Now;
DateTime _time_ = currentTime.AddHours(10);

简单整洁。

最新更新