Ian Jeff
Ian Jeff

Reputation: 25

C# Working days calculation excluding Bank holidays

I have a calculations for checking working days but it's not giving me the right value that I want. Its for annual leave days calculation. So if I input 27 Feb 2017 as start and 03 Mar 2017 as end date it should give me 5 working days holiday but currently it gives me 3. I'm not sure where I went wrong with my calculation. Help is much appreciated thank you.

DateTime firstDay = Convert.ToDateTime(StartDate);
DateTime lastDay = DateTime.Now;

var bankHolidays = new []
{
  new DateTime(2017, 1, 3), // New Year's Day
  new DateTime(2017, 1, 2), // New Year's Day
  new DateTime(2017, 4, 14), // Good Friday
  new DateTime(2017, 4, 17), // Easter Monday
  new DateTime(2017, 5, 1), // Early May Bank Holiday
  new DateTime(2017, 5, 29), // Spring Bank Holiday
  new DateTime(2017, 8, 28), // Summer Bank Holiday
  new DateTime(2017, 12, 25), // Christman Day
  new DateTime(2017, 12, 26), // Boxing Day
  new DateTime(2017, 11, 30), // St Andrews Day
  new DateTime(2017, 3, 17), // St Patricks day
  new DateTime(2017, 7, 12), // Battle of the Boyne
  new DateTime(2016, 1, 1), // New Year's Day
  new DateTime(2016, 3, 25), // Good Friday
  new DateTime(2016, 3, 28), // Easter Monday
  new DateTime(2016, 5, 2), // Early May Bank Holiday
  new DateTime(2016, 5, 30), // Spring Bank Holiday
  new DateTime(2016, 8, 29), // Summer Bank Holiday,
  new DateTime(2016, 12, 26), // Christmas Day
  new DateTime(2016, 12, 27), // Boxing Day 
  new DateTime(2016, 8, 1), // Summer Bank Holiday Scotland,
  new DateTime(2016, 11, 30), //    St Andrew’s Day
  new DateTime(2016, 3, 17), //     St Patrick’s Day
  new DateTime(2016, 7, 12), //     Battle of the Boyne (Orangemen’s Day)
  new DateTime(2016, 1, 4), // 2nd January (substitute day)
  new DateTime(2015, 12, 25), // Christmas 2015
  new DateTime(2015, 12, 28) // Boxing day (substitute day)
}; // I declared all the holidays during year 2017

int Holidays = 0;

if(StartDate == null)
{
return 0;
}
else if(StartDate == EndDate)
{
return 0;
}
else if(!EndDate.HasValue)
{
firstDay = firstDay.AddDays(1).Date;
            lastDay = lastDay.AddDays(0).Date;

     for (var currentDate = firstDay; currentDate <= lastDay; currentDate = currentDate.AddDays(1)) {
            if (currentDate.DayOfWeek != DayOfWeek.Saturday && currentDate.DayOfWeek != DayOfWeek.Sunday && Array.Exists(bankHolidays, o => o.Date == currentDate.Date))
            {
                Holidays++;
            }
        }

            TimeSpan span = lastDay - firstDay;
            int businessDays = span.Days + 1;
            int fullWeekCount = businessDays / 7;

            if (businessDays > fullWeekCount * 7)
            {
                int firstDayOfWeek = firstDay.DayOfWeek == DayOfWeek.Sunday
    ? 7 : (int)firstDay.DayOfWeek;
                int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday
                    ? 7 : (int)lastDay.DayOfWeek;
                if (lastDayOfWeek < firstDayOfWeek)
                    lastDayOfWeek += 7;
                if (firstDayOfWeek <= 6)
                {
                    if (lastDayOfWeek >= 7)
                        businessDays -= 2;
                    else if (lastDayOfWeek >= 6)
                        businessDays -= 1;
                }
                else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)
                    businessDays -= 1;
            }
            businessDays = businessDays -1;
            businessDays = businessDays - Holidays;


      return businessDays -= fullWeekCount + fullWeekCount;
  }
  else
  {
    lastDay = Convert.ToDateTime(EndDate);

    for (var currentDate = firstDay; currentDate <= lastDay; currentDate = currentDate.AddDays(1)) {
        if (currentDate.DayOfWeek != DayOfWeek.Saturday && currentDate.DayOfWeek != DayOfWeek.Sunday && Array.Exists(bankHolidays, o => o.Date == currentDate.Date))
        {
            Holidays++;
        }
    }
      firstDay = firstDay.AddDays(1).Date;
        lastDay = lastDay.AddDays(0).Date;


        TimeSpan span = lastDay - firstDay;
        int businessDays = span.Days + 1;
        int fullWeekCount = businessDays / 7;

        if (businessDays > fullWeekCount * 7)
        {
            int firstDayOfWeek = firstDay.DayOfWeek == DayOfWeek.Sunday
? 7 : (int)firstDay.DayOfWeek;
            int lastDayOfWeek = lastDay.DayOfWeek == DayOfWeek.Sunday
                ? 7 : (int)lastDay.DayOfWeek;
            if (lastDayOfWeek < firstDayOfWeek)
                lastDayOfWeek += 7;
            if (firstDayOfWeek <= 6)
            {
                if (lastDayOfWeek >= 7)
                    businessDays -= 2;
                else if (lastDayOfWeek >= 6)
                    businessDays -= 1;
            }
            else if (firstDayOfWeek <= 7 && lastDayOfWeek >= 7)
                businessDays -= 1;
        }
        businessDays = businessDays -1;
        businessDays = businessDays - Holidays;
        return businessDays -= fullWeekCount + fullWeekCount;
}

Upvotes: 1

Views: 1601

Answers (1)

daniell89
daniell89

Reputation: 2272

Try this approach:

DateTime start = new DateTime(2017, 01, 01);
DateTime end = new DateTime(2017, 01, 10);
TimeSpan ts = end - start;

List<DateTime> workingDays = new List<DateTime>();

for(DateTime dt = start; dt <= end; dt = dt.AddDays(1))
{
    if(dt.DayOfWeek != DayOfWeek.Saturday && dt.DayOfWeek != DayOfWeek.Sunday)
        workingDays.Add(dt);
}

int holidays = workingDays.Intersect(bankHolidays).Count();

int result = workingDays.Count - holidays;

Upvotes: 2

Related Questions