通过考虑时间差计算两个给定日期和时间字段之间的周末数,并以分钟为单位输出差值



我有两个字段startdate和enddate。我需要计算两个日期和时间字段之间的周末数,并以分钟为单位显示结果。

例如,开始日期为01/11/2019 00:00:00,结束日期为03/11/2019 11:00:00。下面的代码将以分钟为单位的差值正确地返回为2100 minutes,但当我将日期保持为02/11/2019 08:0003/11/2019 00:00时,我得到的结果为1440,但我的预期结果是960分钟。

我知道这是因为我在代码中添加了1440,所以如何更正?

public double CountOfWeekEnds(DateTime startDate, DateTime endDate)
{          
double weekEndCount = 0;
if (startDate > endDate)
{
DateTime temp = startDate;
startDate = endDate;
endDate = temp;
}
TimeSpan diff = endDate - startDate;
int days = diff.Days;
for (var i = 0; i <= days; i++)
{
var testDate = startDate.AddDays(i);
if (testDate.DayOfWeek == DayOfWeek.Saturday || testDate.DayOfWeek == DayOfWeek.Sunday)
{
if (testDate.Date < endDate.Date)
{
weekEndCount += 1440; // 24h * 60 min
}
else
{                        
var todayStart = new DateTime(testDate.Year, testDate.Month, testDate.Day, 0, 0, 0);
var difference = (endDate - todayStart).TotalMinutes;
weekEndCount += difference;
}                  
}
}
return weekEndCount;
}

好吧,我把我所说的简化为:

DateTime start = new DateTime(2019,11,1,0,0,0);
DateTime end = new DateTime(2019, 11, 3, 11, 0, 0);
TimeSpan diff = end - start;
Console.WriteLine(diff.TotalDays);
int total = 0;
for (int i = 0; i<Math.Ceiling(diff.TotalDays); i++)
{
DateTime test = start.AddDays(i);
Console.WriteLine(test.DayOfWeek);
if (test.DayOfWeek == DayOfWeek.Saturday ||  test.DayOfWeek == DayOfWeek.Sunday)
{
if (test.Date==start.Date)
{
Console.WriteLine("start");
total += (23 - start.Hour) * 60 + (60 - start.Minute);
}
else if (test.Date==end.Date)
{
Console.WriteLine("end");
total += end.Hour * 60 + end.Minute;
}
else
{
total += 24 * 60;
}
}
Console.WriteLine(test + " total " + total);
}
Console.WriteLine("done");
Console.WriteLine(total);

它统计所有周六和周日,并允许开始和结束作为部分

(有人能寄一个带实际键的键盘吗?这种记忆百灵鸟阻碍了打字(

为了尽可能多地保留原始代码,只需要进行三个小的更改:


1.使用实际日期计算差异:

TimeSpan diff = endDate.Date - startDate.Date;代替TimeSpan diff = endDate - startDate;

这是因为在即将到来的for循环中,你试图评估每个日期,以判断是周六还是周日。否则,您将评估开始时间戳后24(,48,…(小时的日期是周六还是周日。


2.使用testDate而不是todayStart来计算difference

difference = (endDate - testDate).TotalMinutes;

而不是

var todayStart = new DateTime(testDate.Year, testDate.Month, testDate.Day, 0, 0, 0);
var difference = (endDate - todayStart).TotalMinutes;

这是因为testDate确实包含以分钟为单位计算差异的小时和分钟。否则你就忽略了开始一天的时间。请注意,如果startDate日期时间晚于endDate日期时间,则此校正可能导致负值。


3.如果总共只有一天需要检查,则不要增加一整天

这意味着如果startDate。日期==结束日期。日期,您应该计算日期之间的差异。

if (testDate.Date < endDate.Date && startDate.Date != endDate.Date)

必须这样做是因为代码逻辑:除了最后一天之外,每新的一天都会添加一整天,而对于最后一天,根据startDate和endDate的日期时间,将~24小时添加或减去最终值。


完整的校正代码:

public static double CountOfWeekEnds(DateTime startDate, DateTime endDate)
{          
double weekEndCount = 0;
if (startDate > endDate)
{
DateTime temp = startDate;
startDate = endDate;
endDate = temp;
}
TimeSpan diff = endDate.Date - startDate.Date; //instead of endDate - startDate
int days = diff.Days; 
for (var i = 0; i <= days; i++)
{
var testDate = startDate.AddDays(i);
//Console.WriteLine(testDate);
if (testDate.DayOfWeek == DayOfWeek.Saturday || testDate.DayOfWeek == DayOfWeek.Sunday) //only weekends count
{
if (testDate.Date < endDate.Date && startDate.Date != endDate.Date) { // added  startDate.Date != endDate.Date
weekEndCount += 1440; // 24h * 60 min
//Console.WriteLine("************************add 1440 ");
}
else
{    
double difference;
difference = (endDate - testDate).TotalMinutes; //instead of endDate -  todayStart
//Console.WriteLine("************************add " + difference);
weekEndCount += difference;
}                  
}
}
//return days;
return weekEndCount;
}

您需要了解以下条件:

if(testDate.Date<endDate.Date(

这意味着"只要testDate的刻度小于endDate的刻度"。这个条件适用于所有使变量"天数"为正的条件。

我认为你需要扩展这个条件。if((endDate-todayStart(。总分钟数>1440(

通过这种方式,它将检查是否至少提前24小时。如果不是,它应该继续你的"其他"条件,并将开始日的使用分数考虑在内。

这里有一个(有些(简单的解决方案。请注意,如果代码是生产代码,则可以(也可能应该(对其进行重构。但我试图优化它以便于理解,因为这是你的第一篇帖子。。。

public static int CalculateWeekendMinutes(DateTime start, DateTime end)
{
int weekendMinutes = 0;
// First and last day will be handled seperately in the end
var firstFullDay = start.AddDays(1).Date;
var lastFullDay = end.AddDays(-1).Date;
TimeSpan limitedSpan = lastFullDay - firstFullDay;
int spanLengthDays = (int)limitedSpan.TotalDays;
var dateIterator = firstFullDay;
// Looping over the limited span allows us to analyse all the full days
while (dateIterator <= lastFullDay)
{
if (dateIterator.DayOfWeek == DayOfWeek.Saturday || dateIterator.DayOfWeek == DayOfWeek.Sunday)
{
weekendMinutes += (24 * 60);
}   
dateIterator = dateIterator.AddDays(1);
}
// Finally we can calculate the partial days and add that to our total
weekendMinutes += CalculateMinutesOnFirstDay(start);
weekendMinutes += CalculateMinutesOnLastDay(end);
return weekendMinutes;
}
// Helps us calculate the minutes of the first day in the span
private static int CalculateMinutesOnFirstDay(DateTime date)
{
if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
{
// We want to know how many minutes there are UNTIL the next midnight
int minutes = (int)(date.Date.AddDays(1) - date).TotalMinutes;
return minutes;
}
else
{
return 0;
}
}
// Helps us calculate the minutes of the last day in the span
private static int CalculateMinutesOnLastDay(DateTime date)
{
if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
{
// We want to know how many minutes there are SINCE the last midnight
int minutes = (int)(date - date.Date).TotalMinutes;
return minutes;
}
else
{
return 0;
}
}

最新更新