Search code examples
c#date

Verifying logic for counting days between two dates excluding weekends


The goal is to calculate the total number of leave days taken by all employees, broken down by month and year, ensuring weekends are not included in the count . The summation of leave days is returning incorrect values.

public double CalculateLeaveDaysForPeriod(List<EmployeeInfoDto> staffMembers, DateTime periodStart, DateTime periodEnd)
{
    double totalLeaveDays = 0;

    foreach (var staffMember in staffMembers)
    {
        foreach (var leaveRequest in staffMember.LeaveRequests)
        {
            DateTime leaveStartDate = leaveRequest.StartDate;
            DateTime leaveEndDate = leaveRequest.EndDate;

            DateTime validStartDate = leaveStartDate > periodStart ? leaveStartDate : periodStart;
            DateTime validEndDate = leaveEndDate < periodEnd ? leaveEndDate : periodEnd;

            if (validStartDate < validEndDate)
            {
                for (DateTime currentDay = validStartDate; currentDay <= validEndDate; currentDay = currentDay.AddDays(1))
                {
                    if (currentDay.DayOfWeek != DayOfWeek.Saturday && currentDay.DayOfWeek != DayOfWeek.Sunday)
                    {
                        totalLeaveDays++;
                    }
                }
            }
        }
    }
    return totalLeaveDays;
}
 public double GetLeaveDaysForCurrentMonth(List<EmployeeInfoDto> employees)
{
    var currentDate = DateTime.Now;
    var startOfMonth = new DateTime(currentDate.Year, currentDate.Month, 1); 
    var endOfMonth = startOfMonth.AddMonths(1).AddDays(-1); 

    return GetLeaveDaysForTimePeriod(employees, startOfMonth, endOfMonth);
}

public double GetLeaveDaysForCurrentYear(List<EmployeeInfoDto> employees)
{
    var currentDate = DateTime.Now;
    var startOfYear = new DateTime(currentDate.Year, 1, 1); 
    var endOfYear = new DateTime(currentDate.Year, 12, 31); 

    return GetLeaveDaysForTimePeriod(employees, startOfYear, endOfYear);
} 

Here’s an example of the JSON data I’m working with, showing the start and end dates for each employee:

 "leaveRequests": [
    {
      "startDate": "2025-01-07T23:00:00Z",
      "endDate": "2025-01-09T23:00:00Z"
    }
  ]
},
{
  "leaveRequests": [
    {
      "startDate": "2025-01-05T23:00:00Z",
      "endDate": "2025-01-17T23:00:00Z"
    }
  ]
},
{
  "leaveRequests": [
    {
      "startDate": "2025-01-08T23:00:00Z",
      "endDate": "2025-01-23T23:00:00Z"
    }
  ]
}

Solution

  • The time parts may cause you trouble.

    This works for me:

    //DateTime leaveStartDate = new DateTime(2025, 1, 7, 23, 0, 0);
    //DateTime leaveEndDate = new DateTime(2025, 1, 9, 23, 0, 0);
    
    //DateTime leaveStartDate = new DateTime(2025, 1, 5, 23, 0, 0);
    //DateTime leaveEndDate = new DateTime(2025, 1, 17, 23, 0, 0);
    
    //DateTime leaveStartDate = new DateTime(2025, 1, 8, 23, 0, 0);
    //DateTime leaveEndDate = new DateTime(2025, 1, 23, 23, 0, 0);
    
    DateTime leaveStartDate = new DateTime(2025, 1, 8, 23, 0, 0);
    DateTime leaveEndDate = new DateTime(2025, 2, 4, 23, 0, 0);
    
    //DateTime periodStartDate = new DateTime(2025, 1, 1, 0, 0, 0);
    //DateTime periodEndDate = new DateTime(2025, 1, 31, 0, 0, 0);
    
    DateTime periodStartDate = new DateTime(2025, 2, 1, 0, 0, 0);
    DateTime periodEndDate = new DateTime(2025, 2, 28, 0, 0, 0);
    
    DateTime startDate = leaveStartDate.Date > periodStartDate ? leaveStartDate.Date : periodStartDate;
    DateTime endDate = leaveEndDate.Date < periodEndDate ? leaveEndDate.Date : periodEndDate;
    
    DateTime currentDate = startDate;
    int totalLeaveDays = 0;
    
    // To not include endDate as a leave day, use:
    // currentDate < endDate)
    while (currentDate <= endDate)
    {
        if (currentDate.DayOfWeek != DayOfWeek.Saturday && currentDate.DayOfWeek != DayOfWeek.Sunday)
        {
            totalLeaveDays++;
        }
        currentDate = currentDate.AddDays(1);
    };
    
    Console.WriteLine(totalLeaveDays.ToString());
    // 3
    // 10
    // 12