鉴于日期和小时数,我想计算一个新的日期,如果我仅使用工作日小时减去小时数(没有周末小时(没有周六或周日小时))。
我有以下两个函数来计算减去工作日时间的日期。还有更好的方法吗?
static DateTime SubtractWeekdayHours
(
DateTime date2subtractFrom
, int hours2subtract
)
{
if (hours2subtract < 1 || hours2subtract > 120)
throw new Exception("SubtractWeekdayHours() only subtracts hours between 1 and 120 inclusive.");
var weekdayDateTime = DateTime.Now;
// Check if the end of the span touches the weekend:
if (date2subtractFrom.DayOfWeek == DayOfWeek.Saturday || date2subtractFrom.DayOfWeek == DayOfWeek.Sunday)
{
Debug.Write(", End of span EXCEPTION: " + date2subtractFrom.ToString("F"));
var SaturdayStartOf = date2subtractFrom.DayOfWeek == DayOfWeek.Saturday ? date2subtractFrom.Date : date2subtractFrom.AddDays(-1).Date;
weekdayDateTime = SaturdayStartOf.AddHours(-hours2subtract);
}
else
{ // Check if the start of the span touches the weekend:
var possibleWeekendDate = date2subtractFrom.AddHours(-hours2subtract);
if (possibleWeekendDate.DayOfWeek == DayOfWeek.Saturday || possibleWeekendDate.DayOfWeek == DayOfWeek.Sunday)
{
Debug.Write(", Start of span EXCEPTION: " + possibleWeekendDate.ToString("F"));
weekdayDateTime = calculateWeekdayDateTimeWhenSpanTouchesWeekend(possibleWeekendDate, date2subtractFrom, hours2subtract);
}
else
{
var simpleSubtraction = false;
var daysToCheck = hours2subtract / 24;
if (daysToCheck > 0)
{ // Check if any part of the span touches the weekend:
var weekendTouched = false;
for (var x = -daysToCheck; x < 0; x++)
{
possibleWeekendDate = date2subtractFrom.AddDays(x);
if (possibleWeekendDate.DayOfWeek == DayOfWeek.Saturday || possibleWeekendDate.DayOfWeek == DayOfWeek.Sunday)
{
weekendTouched = true;
Debug.Write(", Span EXCEPTION:" + possibleWeekendDate.ToString("F"));
weekdayDateTime = calculateWeekdayDateTimeWhenSpanTouchesWeekend(possibleWeekendDate, date2subtractFrom, hours2subtract);
break;
}
}
if (!weekendTouched)
{ // Span start and end do not touch a weekend and do not span a weekend, so it is just simple subtraction:
simpleSubtraction = true;
}
}
else
{ // Span start and end do not touch a weekend and the number of hours are less than 24, so it is just simple subtraction:
simpleSubtraction = true;
}
if (simpleSubtraction)
{
Debug.Write(", Simple subtraction:");
weekdayDateTime = date2subtractFrom.AddHours(-hours2subtract);
}
}
}
return weekdayDateTime;
}
private static DateTime calculateWeekdayDateTimeWhenSpanTouchesWeekend
(
DateTime weekendDate
, DateTime date2subtractFrom
, int hours2subtract
)
{
var MondayStartOf = weekendDate.DayOfWeek == DayOfWeek.Saturday ? weekendDate.AddDays(2).Date : weekendDate.AddDays(1).Date;
var timeSpan = date2subtractFrom - MondayStartOf;
var hoursLeft = hours2subtract - timeSpan.TotalHours;
var SaturdayStartOf = MondayStartOf.AddDays(-2);
return SaturdayStartOf.AddHours(-hoursLeft);
}
答案 0 :(得分:1)
我相信这会像你描述的那样起作用,但你应该对它进行一些测试。 基本上我要做的就是从循环中的开始日期开始连续减去一小时,如果得到的日期不是我们应该忽略的日期,则减少我们的小时数&#34;反击,直到我们达到零。
此方法允许调用者传入DayOfWeek
(天)列表和应忽略的DateTime
(日期)列表。下面是反映您正在做的事情的实施(忽略周末)。
static DateTime SubtractHours(DateTime startDate, int hours,
List<DayOfWeek> daysToIgnore = null, List<DateTime> datesToIgnore = null)
{
if (hours < 1) throw new ArgumentOutOfRangeException(nameof(hours),
"hours must be a positive integer");
if (daysToIgnore == null) daysToIgnore = new List<DayOfWeek>();
if (datesToIgnore == null) datesToIgnore = new List<DateTime>();
var endDate = startDate;
do
{
// In this loop, we continually subtract an hour from our start date
endDate = endDate.AddHours(-1);
// If that does not result in a day of week or date that
// we should ignore, then subtract one from our hours
if (!daysToIgnore.Any(d => d.Equals(endDate.DayOfWeek)) &&
!datesToIgnore.Any(d => d.Date.Equals(endDate.Date)))
{
hours--;
}
} while (hours > 0);
return endDate;
}
以下是替换您创建的方法的方法:
static DateTime SubtractWeekdayHours(DateTime startDate, int hours)
{
var daysOfWeekToIgnore = new List<DayOfWeek> {DayOfWeek.Saturday, DayOfWeek.Sunday};
return SubtractHours(startDate, hours, daysOfWeekToIgnore);
}
注意:我没有添加最多120小时的限制,但您可以添加该部分!