Calculate the number of weekdays between two dates in C#

前端 未结 11 2230
温柔的废话
温柔的废话 2020-12-03 16:59

How can I get the number of weekdays between two given dates without just iterating through the dates between and counting the weekdays?

Seems fairly straightforward

相关标签:
11条回答
  • 2020-12-03 17:23

    I needed positive / negatives (not absolute values) so here's how I solved it:

        public static int WeekdayDifference(DateTime StartDate, DateTime EndDate)
        {
            DateTime thisDate = StartDate;
            int weekDays = 0;
            while (thisDate != EndDate)
            {
                if (thisDate.DayOfWeek != DayOfWeek.Saturday && thisDate.DayOfWeek != DayOfWeek.Sunday) { weekDays++; }
                if (EndDate > StartDate) { thisDate = thisDate.AddDays(1); } else { thisDate = thisDate.AddDays(-1); }
            }
    
            /* Determine if value is positive or negative */
            if (EndDate > StartDate) {
                return weekDays;
            }
            else
            {
                return weekDays * -1;
            }
        }
    
    0 讨论(0)
  • 2020-12-03 17:27

    O(1) solution:

    // Count days from d0 to d1 inclusive, excluding weekends
    public static int countWeekDays(DateTime d0, DateTime d1)
    {
        int ndays = 1 + Convert.ToInt32((d1 - d0).TotalDays);
        int nsaturdays = (ndays + Convert.ToInt32(d0.DayOfWeek)) / 7;
        return ndays - 2 * nsaturdays
               - (d0.DayOfWeek == DayOfWeek.Sunday ? 1 : 0)
               + (d1.DayOfWeek == DayOfWeek.Saturday ? 1 : 0);
    }
    

    Examples for January 2014:

        January 2014
    Su Mo Tu We Th Fr Sa
              1  2  3  4
     5  6  7  8  9 10 11
    12 13 14 15 16 17 18
    19 20 21 22 23 24 25
    26 27 28 29 30 31
    
    countWeekDays(new DateTime(2014, 1, 1), new DateTime(2014, 1, 1)); // 1
    countWeekDays(new DateTime(2014, 1, 1), new DateTime(2014, 1, 2)); // 2
    countWeekDays(new DateTime(2014, 1, 1), new DateTime(2014, 1, 3)); // 3
    countWeekDays(new DateTime(2014, 1, 1), new DateTime(2014, 1, 4)); // 3
    countWeekDays(new DateTime(2014, 1, 1), new DateTime(2014, 1, 5)); // 3
    countWeekDays(new DateTime(2014, 1, 1), new DateTime(2014, 1, 6)); // 4
    

    N.B. The DateTime inputs should be at around the same time of the day. If you are creating DateTime objects based solely on year, month, and day as in the examples above, then you should be fine. As a counter example, 12:01am on Jan 1 to 11:59pm Jan 2 spans only 2 days, but the above function will count 3 if you use those times.

    0 讨论(0)
  • 2020-12-03 17:29
      public static List<DateTime> Weekdays(DateTime startDate, DateTime endDate)
      {
          if (startDate > endDate)
          {
              Swap(ref startDate, ref endDate);
          }
          List<DateTime> days = new List<DateTime>();
    
          var ts = endDate - startDate;
          for (int i = 0; i < ts.TotalDays; i++)
          {
              var cur = startDate.AddDays(i);
              if (cur.DayOfWeek != DayOfWeek.Saturday && cur.DayOfWeek != DayOfWeek.Sunday)
                  days.Add(cur);
              //if (startingDate.AddDays(i).DayOfWeek != DayOfWeek.Saturday || startingDate.AddDays(i).DayOfWeek != DayOfWeek.Sunday)
              //yield return startingDate.AddDays(i);
          }
          return days;
      }
    

    And swap dates

      private static void Swap(ref DateTime startDate, ref DateTime endDate)
      {
          object a = startDate;
          startDate = endDate;
          endDate = (DateTime)a;
      }
    
    0 讨论(0)
  • 2020-12-03 17:34

    This should do better than the solution by dcp:

        /// <summary>
        /// Count Weekdays between two dates
        /// </summary>
        /// <param name="dtmStart">first date</param>
        /// <param name="dtmEnd">second date</param>
        /// <returns>weekdays between the two dates, including the start and end day</returns>
        internal static int getWeekdaysBetween(DateTime dtmStart, DateTime dtmEnd)
        {
            if (dtmStart > dtmEnd)
            {
                DateTime temp = dtmStart;
                dtmStart = dtmEnd;
                dtmEnd = temp;
            }
    
            /* Move border dates to the monday of the first full week and sunday of the last week */
            DateTime startMonday = dtmStart;
            int startDays = 1;
            while (startMonday.DayOfWeek != DayOfWeek.Monday)
            {
                if (startMonday.DayOfWeek != DayOfWeek.Saturday && startMonday.DayOfWeek != DayOfWeek.Sunday)
                {
                    startDays++;
                }
                startMonday = startMonday.AddDays(1);
            }
    
            DateTime endSunday = dtmEnd;
            int endDays = 0;
            while (endSunday.DayOfWeek != DayOfWeek.Sunday)
            {
                if (endSunday.DayOfWeek != DayOfWeek.Saturday && endSunday.DayOfWeek != DayOfWeek.Sunday)
                {
                    endDays++;
                }
                endSunday = endSunday.AddDays(1);
            }
    
            int weekDays;
    
            /* calculate weeks between full week border dates and fix the offset created by moving the border dates */
            weekDays = (Math.Max(0, (int)Math.Ceiling((endSunday - startMonday).TotalDays + 1)) / 7 * 5) + startDays - endDays;
    
            return weekDays;
        }
    
    0 讨论(0)
  • 2020-12-03 17:35
    var dates = new List<DateTime>();
    
            for (var dt = YourStartDate; dt <= YourEndDate; dt = dt.AddDays(1))
            {
    
                if (dt.DayOfWeek != DayOfWeek.Sunday && dt.DayOfWeek != DayOfWeek.Saturday)
                { dates.Add(dt); }
    
            }
    

    in this code you could have a list that all buisness days between two dates.

    if you want the count of these dates you could get dates.Count as an integer. or if you want to get the each day , you could join the list to a string.

    0 讨论(0)
  • 2020-12-03 17:37

    From this link:

        public static int Weekdays(DateTime dtmStart, DateTime dtmEnd)
        {
            // This function includes the start and end date in the count if they fall on a weekday
            int dowStart = ((int)dtmStart.DayOfWeek == 0 ? 7 : (int)dtmStart.DayOfWeek);
            int dowEnd = ((int)dtmEnd.DayOfWeek == 0 ? 7 : (int)dtmEnd.DayOfWeek);
            TimeSpan tSpan = dtmEnd - dtmStart;
            if (dowStart <= dowEnd)
            {
                return (((tSpan.Days / 7) * 5) + Math.Max((Math.Min((dowEnd + 1), 6) - dowStart), 0));
            }
            return (((tSpan.Days / 7) * 5) + Math.Min((dowEnd + 6) - Math.Min(dowStart, 6), 5));
        }
    
    
      [1]: http://www.eggheadcafe.com/community/aspnet/2/44982/how-to-calculate-num-of-w.aspx
    

    Tests (each test returns 5):

        int ndays = Weekdays(new DateTime(2009, 11, 30), new DateTime(2009, 12, 4));
        System.Console.WriteLine(ndays);
    
        // leap year test
        ndays = Weekdays(new DateTime(2000, 2,27), new DateTime(2000, 3, 5));
        System.Console.WriteLine(ndays);
    
        // non leap year test
        ndays = Weekdays(new DateTime(2007, 2, 25), new DateTime(2007, 3, 4));
        System.Console.WriteLine(ndays);
    
    0 讨论(0)
提交回复
热议问题