【问题标题】:Calculating no of weekends in between the two given date and time fields by considering the time difference and output the difference in minutes通过考虑时差计算两个给定日期和时间字段之间的周末数并以分钟为单位输出差
【发布时间】:2019-11-12 00:12:51
【问题描述】:

我有两个字段 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;
    }

【问题讨论】:

  • 嘿,说清楚一点。您想计算您的时间跨度内的周末分钟数吗?
  • 是的,没错。谢谢诺西奥
  • 好吧,如果不是第一天或最后一天,假设 24 小时,如果不是 sat 或 sun 添加 0 否则添加 max mins,然后根据指定的时间整理第一天和最后一天
  • @BugFinder - 您能否在代码中显示出来。谢谢

标签: c#


【解决方案1】:

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

        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);

计算所有星期六和星期日,并允许开始和结束是部分的

(有人可以发送一个带有实际按键的键盘吗?这个大脑云雀会妨碍打字)

【讨论】:

  • 您好 BugFinder,当我测试上面的代码时,通过以下示例我得到了错误的计算。请你看看开始日期为 02/11/2019 00:00 和 02/11/2019 16:00
  • 好的,谢谢,我认为代码中存在一些错误,这就是我回复您的原因。我会努力解决这个问题。
  • 我从来没有说过它在同一天处理:P 然而,它应该不难修复,同时如果你弄清楚为什么而不是我只是为你修复它,它将帮助你更好地理解它
【解决方案2】:

尽量保留原始代码,只需要进行三处小改动:


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.Date == endDate.Date,您应该只计算日期之间的差异。

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

由于代码逻辑,必须这样做:除了最后一天之外,每个新的一天都会添加一整天,而对于最后一天,根据一天的时间将〜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;
}

【讨论】:

    【解决方案3】:

    你需要看看这个条件:

    if (testDate.Date

    意思是“只要testDate的滴答声小于endDate的滴答声”。 对于使变量“天”为正的所有条件,此条件都将成立。

    我认为您需要扩展此条件,例如 if ((endDate - todayStart).TotalMinutes > 1440 )

    这样它会检查它是否至少提前 24 小时。如果不是,则应继续使用您的“其他”条件,并考虑开始日的已使用部分。

    【讨论】:

      【解决方案4】:

      这是一个(有点)简单的解决方案。请注意,如果要成为生产代码,则可以(并且可能应该)重构代码。但我尝试对其进行优化以使其易于理解,因为这是您的第一篇文章...

      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;
          }
      }
      

      【讨论】:

      • 嗨 Noceo,如果我以 31/10/2019 00:00 和 04/11/2019 12:00 为例,上面的代码给出了错误的答案。请你看看。谢谢
      • 我的错,我在移动代码时忘记了一些东西。它现在应该可以工作了。虽然对于生产实现,我会使用@BugFinder 的解决方案,尽管有更多的 cmets :-)
      • 好的,谢谢 - Noceo
      猜你喜欢
      • 1970-01-01
      • 2011-11-29
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多