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

C# 通过考虑时间差计算两个给定日期和时间字段之间的周末数,并以分钟为单位输出差异,c#,C#,我有两个字段startdate和enddate。我需要计算两个日期和时间字段之间的周末数,并以分钟为单位显示结果 例如,开始日期为2019年11月1日00:00:00,结束日期为2019年11月3日11:00:00。下面的代码将分钟差正确返回为2100分钟,但当我将日期保留为2019年11月02日08:00和2019年11月03日00:00时,我得到的结果是1440但我的预期结果是960分钟 我明白这是因为我在代码中添加了1440,那么如何纠正这个问题呢 public double CountO

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

例如,开始日期为
2019年11月1日00:00:00
,结束日期为
2019年11月3日11:00:00
。下面的代码将分钟差正确返回为
2100分钟
,但当我将日期保留为
2019年11月02日08:00
2019年11月03日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;
    }
public double CountOfWeekEnds(DateTime startDate,DateTime endDate)
{          
双周数=0;
如果(开始日期>结束日期)
{
日期时间温度=开始日期;
开始日期=结束日期;
结束日期=温度;
}
TimeSpan diff=结束日期-开始日期;
整数天=差异天;
对于(var i=0;i,这里有一个(有些)简单的解决方案。请注意,如果代码是生产代码,则可以(也可能应该)对其进行重构。但我尝试对其进行优化以便于理解,因为这是您的第一篇博文

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;
    }
}
public static int CalculateWeekendMinutes(日期时间开始,日期时间结束)
{
int weekendMinutes=0;
//最后,第一天和最后一天将分别处理
var firstFullDay=start.AddDays(1.Date);
var lastFullDay=end.AddDays(-1).Date;
TimeSpan limitedSpan=lastFullDay-firstFullDay;
int spanLengthDays=(int)limitedSpan.TotalDays;
var dateIterator=firstFullDay;
//在有限的跨度上循环可以让我们分析所有的时间

而(dateIterator您需要查看以下情况:

if(testDate.Date 这意味着“只要testDate的刻度小于endDate的刻度”。 对于使变量“天”为正的所有条件,此条件均为真

我认为你需要延长这个条件。 如果((结束日期-今天开始).TotalMinutes>1440)


这样,它将检查是否至少提前24小时。如果不是,则应根据您的“else”条件,并考虑开始一天中使用的部分。

好的,我将我说的话简化为:

        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);
DateTime start=新的日期时间(2019,11,1,0,0,0);
DateTime end=新的日期时间(2019,11,3,11,0,0);
TimeSpan diff=结束-开始;
控制台写入线(差异总天数);
int-total=0;

对于(int i=0;i试图尽可能多地保留原始代码,只需进行三个小的更改:


1.使用实际日期计算差异:
TimeSpan diff=endDate.Date-startDate.Date;
而不是
TimeSpan diff=endDate-startDate;

这是因为在接下来的for循环中,您将尝试评估每个日期,以确定是周六还是周日。否则,您将评估开始时间戳后24(,48,…)小时的日期是周六还是周日


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

var todayStart = new DateTime(testDate.Year, testDate.Month, testDate.Day, 0, 0, 0);
var difference = (endDate - todayStart).TotalMinutes;
这是因为testDate确实包含以分钟为单位计算差异的小时和分钟数。否则,您只会忽略开始日的日时间。请注意,如果startDate日时间晚于endDate日时间,此更正可能会导致负差异值


3.如果总共只有一天要检查,则不要增加一整天 这意味着如果startDate.Date==endDate.Date,您应该只计算两个日期之间的差异

if (testDate.Date < endDate.Date && startDate.Date != endDate.Date)
if(testDate.Date
由于代码逻辑,必须这样做:除了最后一天之外,每增加一天,就增加一整天;对于最后一天,根据开始日期和结束日期的天数,将24小时加到或减去最终值


完整的更正代码:
publicstaticdouble CountOfWeekEnds(DateTime startDate,DateTime endDate)
{          
双周数=0;
如果(开始日期>结束日期)
{
日期时间温度=开始日期;
开始日期=结束日期;
结束日期=温度;
}
TimeSpan diff=endDate.Date-startDate.Date;//而不是endDate-startDate
整数天=差异天;

对于(var i=0;i嘿,我只是想澄清一下。你想计算你的时间跨度内的周末分钟数吗?是的,这是正确的。谢谢你。好吧,如果不是第一天或最后一天,假设24小时,如果不是周六或周日,则加0,否则加上最长分钟,然后根据时间安排第一天和最后一天specified@BugFinder-你能用代码显示一下吗?谢谢sHi Noceo,如果我以2019年10月31日00:00和2019年11月4日12:00为例,上面的代码给出了错误的答案。请你看一看。谢天谢地,我在移动代码时忘记了一些东西。现在应该可以了。不过对于生产实现,我会使用@BugFinder的解决方案,尽管还有一些注释:-)好的,谢谢你-NoceoHi BugFinder,当我测试上述代码时,以下示例中的计算结果是错误的。请你看看开始日期是2019年11月2日00:00和2019年11月2日16:00好的,谢谢你,我认为代码中有一些错误,这就是我返回给你的原因。我会解决这个问题。我从来没有说过它可以处理d同一天:P然而,它不应该很难修复,同时,如果你找出原因,而不是我帮你修复它,它将帮助你更好地理解它
if (testDate.Date < endDate.Date && startDate.Date != endDate.Date)
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;
}