我想计算两个日期之间以小时和分钟为单位的时间。但也减去那个时期的某些时间和日期。
示例:
DateTime startDate = new DateTime(2022,10,8,14,35,1)
DateTime endDate = new DateTime(2022,11,1,17,46,62)
通过以下方式:
Timespan ts = endDate.Subtract(starDate);
我在两天之间有整个时间。
但我一直想在以下几个方面减去:
f 211
我可以得到正确的结果,但不是很有效率。
伪码:
int seconds = 0
while(startDate <= endDate)
{
if(startDate not in excludedTime)
seconds++;
startDate = startDate.AddSeconds(1);
}
一定有更有效的方法吗?
发布于 2022-11-15 19:25:34
一种方法是根据周末/假日规则调整日期,另一种方法是根据工作时间规则从一天中获取时间范围,第三种方法是利用这些方法在一定范围内计算每天的时差。
对于第一种方法,我添加了一个bool forward
参数,我们可以将其设置为false
来调整结束日期,因为向后移动日期的实现可能略有不同。注意,当将一天移到新的一天时,我使用结果的.Date
属性重置时间信息:
public static DateTime AdjustDate(DateTime input, bool forward = true)
{
var skipDates = new List<DateTime>
{
// add a comma-separated list of dates to skip here
};
while (skipDates.Contains(input.Date))
input = input.AddDays(forward ? 1 : -1).Date;
if (input.DayOfWeek == DayOfWeek.Saturday)
input = input.AddDays(forward ? 2 : -1).Date;
if (input.DayOfWeek == DayOfWeek.Sunday)
input = input.AddDays(forward ? 1 : -2).Date;
return input;
}
一旦我们使用了这个方法,我们就需要一种方法,让我们在一天中特定的工作时间内工作。再一次,我们有一个bool参数,指定我们是从一天开始还是从一天结束计算小时数。然后,我们可以添加逻辑来调整日期的实际时间,并根据指定的一天开始和结束时间进行计算。
public static TimeSpan GetNetTimeSpan(DateTime input, bool fromStart = true)
{
if (input.Hour > 19)
{
if (fromStart)
input = new DateTime(input.Year, input.Month, input.Day, 19, 0, 0);
else return TimeSpan.Zero;
}
if (input.Hour < 8)
{
if (fromStart) return TimeSpan.Zero;
else input = new DateTime(input.Year, input.Month, input.Day, 8, 0, 0);
}
if (fromStart)
{
return input - new DateTime(input.Year, input.Month, input.Day, 8, 0, 0);
}
else
{
return new DateTime(input.Year, input.Month, input.Day, 19, 0, 0) - input;
}
}
有了这些功能之后,我们现在应该能够遍历所有的日子,并创建一个时间周期来封装每一天的有效刻度:
public static TimeSpan GetNetDifference(DateTime start, DateTime end)
{
// First, adjust our start and end dates to avoid weekends and holidays
start = AdjustDate(start);
end = AdjustDate(end, false);
// If our start is no longer less than our end, return zero
if (start >= end) return TimeSpan.Zero;
// Begin with the start date timespan
var result = GetNetTimeSpan(start);
// Next loop through each day between start and end and add them to the result
var current = AdjustDate(start.AddDays(1).Date);
while(current.Date < end.Date)
{
result += GetNetTimeSpan(current);
current = AdjustDate(current.AddDays(1).Date);
}
// Add our last day and return the result
return result + GetNetTimeSpan(end);
}
我没有测试它,部分原因是它不完全清楚这是否符合您的规则,但它应该给您一个好的起点。
此外,如果我们将开始和结束时间参数化,而不是让它们在8和19处硬编码,那么它将更加灵活。
https://stackoverflow.com/questions/74454384
复制