AddBusinessDays and GetBusinessDays

C#.Net

C# Problem Overview


I need to find 2 elegant complete implementations of

public static DateTime AddBusinessDays(this DateTime date, int days)
{
 // code here
}

and 

public static int GetBusinessDays(this DateTime start, DateTime end)
{
 // code here
}

O(1) preferable (no loops).

EDIT: By business days i mean working days (Monday, Tuesday, Wednesday, Thursday, Friday). No holidays, just weekends excluded.

I already have some ugly solutions that seem to work but i wonder if there are elegant ways to do this. Thanks


This is what i've written so far. It works in all cases and does negatives too. Still need a GetBusinessDays implementation

public static DateTime AddBusinessDays(this DateTime startDate,
                                         int businessDays)
{
	int direction = Math.Sign(businessDays);
	if(direction == 1)
	{
		if(startDate.DayOfWeek == DayOfWeek.Saturday)
		{
			startDate = startDate.AddDays(2);
			businessDays = businessDays - 1;
		}
		else if(startDate.DayOfWeek == DayOfWeek.Sunday)
		{
			startDate = startDate.AddDays(1);
			businessDays = businessDays - 1;
		}
	}
	else
	{
		if(startDate.DayOfWeek == DayOfWeek.Saturday)
		{
			startDate = startDate.AddDays(-1);
			businessDays = businessDays + 1;
		}
		else if(startDate.DayOfWeek == DayOfWeek.Sunday)
		{
			startDate = startDate.AddDays(-2);
			businessDays = businessDays + 1;
		}
	}
  
	int initialDayOfWeek = (int)startDate.DayOfWeek;

	int weeksBase = Math.Abs(businessDays / 5);
	int addDays = Math.Abs(businessDays % 5);

	if((direction == 1 && addDays + initialDayOfWeek > 5) ||
	     (direction == -1 && addDays >= initialDayOfWeek))
	{
		addDays += 2;
	}

	int totalDays = (weeksBase * 7) + addDays;
	return startDate.AddDays(totalDays * direction);
}

C# Solutions


Solution 1 - C#

Latest attempt for your first function:

public static DateTime AddBusinessDays(DateTime date, int days)
{
    if (days < 0)
    {
        throw new ArgumentException("days cannot be negative", "days");
    }

    if (days == 0) return date;

    if (date.DayOfWeek == DayOfWeek.Saturday)
    {
        date = date.AddDays(2);
        days -= 1;
    }
    else if (date.DayOfWeek == DayOfWeek.Sunday)
    {
        date = date.AddDays(1);
        days -= 1;
    }

    date = date.AddDays(days / 5 * 7);
    int extraDays = days % 5;

    if ((int)date.DayOfWeek + extraDays > 5)
    {
        extraDays += 2;
    }

    return date.AddDays(extraDays);

}

The second function, GetBusinessDays, can be implemented as follows:

public static int GetBusinessDays(DateTime start, DateTime end)
{
    if (start.DayOfWeek == DayOfWeek.Saturday)
    {
        start = start.AddDays(2);
    }
    else if (start.DayOfWeek == DayOfWeek.Sunday)
    {
        start = start.AddDays(1);
    }

    if (end.DayOfWeek == DayOfWeek.Saturday)
    {
        end = end.AddDays(-1);
    }
    else if (end.DayOfWeek == DayOfWeek.Sunday)
    {
        end = end.AddDays(-2);
    }

    int diff = (int)end.Subtract(start).TotalDays;

    int result = diff / 7 * 5 + diff % 7;

    if (end.DayOfWeek < start.DayOfWeek)
    {
        return result - 2;
    }
    else{
        return result;
    }
}

Solution 2 - C#

using Fluent DateTime:

var now = DateTime.Now;
var dateTime1 = now.AddBusinessDays(3);
var dateTime2 = now.SubtractBusinessDays(5);

internal code is as follows

    /// <summary>
    /// Adds the given number of business days to the <see cref="DateTime"/>.
    /// </summary>
    /// <param name="current">The date to be changed.</param>
    /// <param name="days">Number of business days to be added.</param>
    /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
    public static DateTime AddBusinessDays(this DateTime current, int days)
    {
        var sign = Math.Sign(days);
        var unsignedDays = Math.Abs(days);
        for (var i = 0; i < unsignedDays; i++)
        {
            do
            {
                current = current.AddDays(sign);
            }
            while (current.DayOfWeek == DayOfWeek.Saturday ||
                current.DayOfWeek == DayOfWeek.Sunday);
        }
        return current;
    }

    /// <summary>
    /// Subtracts the given number of business days to the <see cref="DateTime"/>.
    /// </summary>
    /// <param name="current">The date to be changed.</param>
    /// <param name="days">Number of business days to be subtracted.</param>
    /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
    public static DateTime SubtractBusinessDays(this DateTime current, int days)
    {
        return AddBusinessDays(current, -days);
    }

Solution 3 - C#

I created an extension that allows you to add or subtract business days. Use a negative number of businessDays to subtract. I think it's quite an elegant solution. It seems to work in all cases.

namespace Extensions.DateTime
{
    public static class BusinessDays
    {
        public static System.DateTime AddBusinessDays(this System.DateTime source, int businessDays)
        {
            var dayOfWeek = businessDays < 0
                                ? ((int)source.DayOfWeek - 12) % 7
                                : ((int)source.DayOfWeek + 6) % 7;

            switch (dayOfWeek)
            {
                case 6:
                    businessDays--;
                    break;
                case -6:
                    businessDays++;
                    break;
            }

            return source.AddDays(businessDays + ((businessDays + dayOfWeek) / 5) * 2);
        }
    }
}

Example:

using System;
using System.Windows.Forms;
using Extensions.DateTime;

namespace AddBusinessDaysTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            label1.Text = DateTime.Now.AddBusinessDays(5).ToString();
            label2.Text = DateTime.Now.AddBusinessDays(-36).ToString();
        }
    }
}

Solution 4 - C#

For me I had to have a solution that would skip weekends and go in either negative or positive. My criteria was if it went forward and landed on a weekend it would need to advance to Monday. If it was going back and landed on a weekend it would have to jump to Friday.

> For example: > > - Wednesday - 3 business days = Last Friday > - Wednesday + 3 business days = Monday > - Friday - 7 business days = Last Wednesday > - Tuesday - 5 business days = Last Tuesday

Well you get the idea ;)

I ended up writing this extension class

public static partial class MyExtensions
{
	public static DateTime AddBusinessDays(this DateTime date, int addDays)
	{
		while (addDays != 0)
		{
			date = date.AddDays(Math.Sign(addDays));
			if (MyClass.IsBusinessDay(date))
			{
				addDays = addDays - Math.Sign(addDays);
			}
		}
		return date;
	}
}

It uses this method I thought would be useful to use elsewhere...

public class MyClass
{
	public static bool IsBusinessDay(DateTime date)
    {
        switch (date.DayOfWeek)
        {
            case DayOfWeek.Monday:
            case DayOfWeek.Tuesday:
            case DayOfWeek.Wednesday:
            case DayOfWeek.Thursday:
            case DayOfWeek.Friday:
                return true;
            default:
                return false;
        }
    }
}

If you don't want to bother with that you can just replace out if (MyClass.IsBusinessDay(date)) with if if ((date.DayOfWeek != DayOfWeek.Saturday) && (date.DayOfWeek != DayOfWeek.Sunday))

So now you can do

var myDate = DateTime.Now.AddBusinessDays(-3);

or

var myDate = DateTime.Now.AddBusinessDays(5);

Here are the results from some testing:

Test	                     Expected	Result
Wednesday -4 business days	 Thursday	Thursday
Wednesday -3 business days	 Friday   	Friday
Wednesday +3 business days	 Monday	    Monday
Friday -7 business days	     Wednesday	Wednesday
Tuesday -5 business days	 Tuesday	Tuesday
Friday +1 business days	     Monday	    Monday
Saturday +1 business days	 Monday	    Monday
Sunday -1 business days	     Friday	    Friday
Monday -1 business days	     Friday	    Friday
Monday +1 business days	     Tuesday	Tuesday
Monday +0 business days	     Monday	    Monday

Solution 5 - C#

public static DateTime AddBusinessDays(this DateTime date, int days)
{
    date = date.AddDays((days / 5) * 7);

    int remainder = days % 5;

    switch (date.DayOfWeek)
    {
        case DayOfWeek.Tuesday:
            if (remainder > 3) date = date.AddDays(2);
            break;
        case DayOfWeek.Wednesday:
            if (remainder > 2) date = date.AddDays(2);
            break;
        case DayOfWeek.Thursday:
            if (remainder > 1) date = date.AddDays(2);
            break;
        case DayOfWeek.Friday:
            if (remainder > 0) date = date.AddDays(2);
            break;
        case DayOfWeek.Saturday:
            if (days > 0) date = date.AddDays((remainder == 0) ? 2 : 1);
            break;
        case DayOfWeek.Sunday:
            if (days > 0) date = date.AddDays((remainder == 0) ? 1 : 0);
            break;
        default:  // monday
            break;
    }

    return date.AddDays(remainder);
}

Solution 6 - C#

The only real solution is to have those calls access a database table that defines the calendar for your business. You could code it for a Monday to Friday workweek without too much difficult but handling holidays would be a challenge.

Edited to add non-elegant and non-tested partial solution:

public static DateTime AddBusinessDays(this DateTime date, int days)
{
    for (int index = 0; index < days; index++)
    {
        switch (date.DayOfWeek)
        {
            case DayOfWeek.Friday:
                date = date.AddDays(3);
                break;
            case DayOfWeek.Saturday:
                date = date.AddDays(2);
                break;
            default:
                date = date.AddDays(1);
                break;
         }
    }
    return date;
}

Also I violated the no loops requirement.

Solution 7 - C#

I'm coming late for the answer, but I made a little library with all the customization needed to do simple operations on working days... I leave it here : Working Days Management

Solution 8 - C#

I am resurrecting this post because today I had to find a way to exclude not only Saturday and Sunday weekdays but also holidays. More specifically, I needed to handle various sets of possible holidays, including:

  • country-invariant holidays (at least for the Western countries - such as January, 01).
  • calculated holidays (such as Easter and Easter monday).
  • country-specific holidays (such as the Italian liberation day or the United States ID4).
  • town-specific holidays (such as the Rome St. Patron Day).
  • any other custom-made holiday (such as "tomorrow our office wil be closed").

Eventually, I came out with the following set of helper/extensions classes: although they aren't blatantly elegant, as they do make a massive use of unefficient loops, they are decent enough to solve my issues for good. I'm dropping the whole source code here in this post, hoping it will be useful to someone else as well.

Source code

/// <summary>
/// Helper/extension class for manipulating date and time values.
/// </summary>
public static class DateTimeExtensions
{
    /// <summary>
    /// Calculates the absolute year difference between two dates.
    /// </summary>
    /// <param name="dt1"></param>
    /// <param name="dt2"></param>
    /// <returns>A whole number representing the number of full years between the specified dates.</returns>
    public static int Years(DateTime dt1,DateTime dt2)
	{
		return Months(dt1,dt2)/12;
		//if (dt2<dt1)
		//{
		//    DateTime dt0=dt1;
		//    dt1=dt2;
		//    dt2=dt0;
		//}

		//int diff=dt2.Year-dt1.Year;
		//int m1=dt1.Month;
		//int m2=dt2.Month;
		//if (m2>m1) return diff;
		//if (m2==m1 && dt2.Day>=dt1.Day) return diff;
		//return (diff-1);
	}

    /// <summary>
    /// Calculates the absolute year difference between two dates.
    /// Alternative, stand-alone version (without other DateTimeUtil dependency nesting required)
    /// </summary>
    /// <param name="start"></param>
    /// <param name="end"></param>
    /// <returns></returns>
    public static int Years2(DateTime start, DateTime end)
    {
        return (end.Year - start.Year - 1) +
            (((end.Month > start.Month) ||
            ((end.Month == start.Month) && (end.Day >= start.Day))) ? 1 : 0);
    }

    /// <summary>
    /// Calculates the absolute month difference between two dates.
    /// </summary>
    /// <param name="dt1"></param>
    /// <param name="dt2"></param>
    /// <returns>A whole number representing the number of full months between the specified dates.</returns>
    public static int Months(DateTime dt1,DateTime dt2)
	{
		if (dt2<dt1)
		{
			DateTime dt0=dt1;
			dt1=dt2;
			dt2=dt0;
		}

		dt2=dt2.AddDays(-(dt1.Day-1));
		return (dt2.Year-dt1.Year)*12+(dt2.Month-dt1.Month);
	}

	/// <summary>
	/// Returns the higher of the two date time values.
	/// </summary>
	/// <param name="dt1">The first of the two <c>DateTime</c> values to compare.</param>
	/// <param name="dt2">The second of the two <c>DateTime</c> values to compare.</param>
	/// <returns><c>dt1</c> or <c>dt2</c>, whichever is higher.</returns>
	public static DateTime Max(DateTime dt1,DateTime dt2)
	{
		return (dt2>dt1?dt2:dt1);
	}

	/// <summary>
	/// Returns the lower of the two date time values.
	/// </summary>
	/// <param name="dt1">The first of the two <c>DateTime</c> values to compare.</param>
	/// <param name="dt2">The second of the two <c>DateTime</c> values to compare.</param>
	/// <returns><c>dt1</c> or <c>dt2</c>, whichever is lower.</returns>
	public static DateTime Min(DateTime dt1,DateTime dt2)
	{
		return (dt2<dt1?dt2:dt1);
	}

    /// <summary>
    /// Adds the given number of business days to the <see cref="DateTime"/>.
    /// </summary>
    /// <param name="current">The date to be changed.</param>
    /// <param name="days">Number of business days to be added.</param>
    /// <param name="holidays">An optional list of holiday (non-business) days to consider.</param>
    /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
    public static DateTime AddBusinessDays(
        this DateTime current, 
        int days, 
        IEnumerable<DateTime> holidays = null)
    {
        var sign = Math.Sign(days);
        var unsignedDays = Math.Abs(days);
        for (var i = 0; i < unsignedDays; i++)
        {
            do
            {
                current = current.AddDays(sign);
            }
            while (current.DayOfWeek == DayOfWeek.Saturday
                || current.DayOfWeek == DayOfWeek.Sunday
                || (holidays != null && holidays.Contains(current.Date))
                );
        }
        return current;
    }

    /// <summary>
    /// Subtracts the given number of business days to the <see cref="DateTime"/>.
    /// </summary>
    /// <param name="current">The date to be changed.</param>
    /// <param name="days">Number of business days to be subtracted.</param>
    /// <param name="holidays">An optional list of holiday (non-business) days to consider.</param>
    /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
    public static DateTime SubtractBusinessDays(
        this DateTime current, 
        int days,
        IEnumerable<DateTime> holidays)
    {
        return AddBusinessDays(current, -days, holidays);
    }

    /// <summary>
    /// Retrieves the number of business days from two dates
    /// </summary>
    /// <param name="startDate">The inclusive start date</param>
    /// <param name="endDate">The inclusive end date</param>
    /// <param name="holidays">An optional list of holiday (non-business) days to consider.</param>
    /// <returns></returns>
    public static int GetBusinessDays(
        this DateTime startDate, 
        DateTime endDate,
        IEnumerable<DateTime> holidays)
    {
        if (startDate > endDate)
            throw new NotSupportedException("ERROR: [startDate] cannot be greater than [endDate].");

        int cnt = 0;
        for (var current = startDate; current < endDate; current = current.AddDays(1))
        {
            if (current.DayOfWeek == DayOfWeek.Saturday
                || current.DayOfWeek == DayOfWeek.Sunday
                || (holidays != null && holidays.Contains(current.Date))
                )
            {
                // skip holiday
            }
            else cnt++;
        }
        return cnt;
    }

    /// <summary>
    /// Calculate Easter Sunday for any given year.
    /// src.: https://stackoverflow.com/a/2510411/1233379
    /// </summary>
    /// <param name="year">The year to calcolate Easter against.</param>
    /// <returns>a DateTime object containing the Easter month and day for the given year</returns>
    public static DateTime GetEasterSunday(int year)
    {
        int day = 0;
        int month = 0;

        int g = year % 19;
        int c = year / 100;
        int h = (c - (int)(c / 4) - (int)((8 * c + 13) / 25) + 19 * g + 15) % 30;
        int i = h - (int)(h / 28) * (1 - (int)(h / 28) * (int)(29 / (h + 1)) * (int)((21 - g) / 11));

        day = i - ((year + (int)(year / 4) + i + 2 - c + (int)(c / 4)) % 7) + 28;
        month = 3;

        if (day > 31)
        {
            month++;
            day -= 31;
        }

        return new DateTime(year, month, day);
    }

    /// <summary>
    /// Retrieve holidays for given years
    /// </summary>
    /// <param name="years">an array of years to retrieve the holidays</param>
    /// <param name="countryCode">a country two letter ISO (ex.: "IT") to add the holidays specific for that country</param>
    /// <param name="cityName">a city name to add the holidays specific for that city</param>
    /// <returns></returns>
    public static IEnumerable<DateTime> GetHolidays(IEnumerable<int> years, string countryCode = null, string cityName = null)
    {
        var lst = new List<DateTime>();

        foreach (var year in years.Distinct())
        {
            lst.AddRange(new[] {
                new DateTime(year, 1, 1),       // 1 gennaio (capodanno)
                new DateTime(year, 1, 6),       // 6 gennaio (epifania)
                new DateTime(year, 5, 1),       // 1 maggio (lavoro)
                new DateTime(year, 8, 15),      // 15 agosto (ferragosto)
                new DateTime(year, 11, 1),      // 1 novembre (ognissanti)
                new DateTime(year, 12, 8),      // 8 dicembre (immacolata concezione)
                new DateTime(year, 12, 25),     // 25 dicembre (natale)
                new DateTime(year, 12, 26)      // 26 dicembre (s. stefano)
            });

            // add easter sunday (pasqua) and monday (pasquetta)
            var easterDate = GetEasterSunday(year);
            lst.Add(easterDate);
            lst.Add(easterDate.AddDays(1));

            // country-specific holidays
            if (!String.IsNullOrEmpty(countryCode))
            {
                switch (countryCode.ToUpper())
                {
                    case "IT":
                        lst.Add(new DateTime(year, 4, 25));     // 25 aprile (liberazione)
                        break;
                    case "US":
                        lst.Add(new DateTime(year, 7, 4));     // 4 luglio (Independence Day)
                        break;

                    // todo: add other countries

                    case default:
                        // unsupported country: do nothing
                        break;
                }
            }

            // city-specific holidays
            if (!String.IsNullOrEmpty(cityName))
            {
                switch (cityName)
                {
                    case "Rome":
                    case "Roma":
                        lst.Add(new DateTime(year, 6, 29));  // 29 giugno (s. pietro e paolo)
                        break;
                    case "Milano":
                    case "Milan":
                        lst.Add(new DateTime(year, 12, 7));  // 7 dicembre (s. ambrogio)
                        break;

                    // todo: add other cities

                    default:
                        // unsupported city: do nothing
                        break;

                }
            }
        }
        return lst;
    }
}

Usage info

The code is quite self-explanatory, however here's a couple examples to explain how you can use it.

Add 10 business days (skipping only saturday and sunday week days)

var dtResult = DateTimeUtil.AddBusinessDays(srcDate, 10);

Add 10 business days (skipping saturday, sunday and all country-invariant holidays for 2019)

var dtResult = DateTimeUtil.AddBusinessDays(srcDate, 10, GetHolidays(2019));

Add 10 business days (skipping saturday, sunday and all italian holidays for 2019)

var dtResult = DateTimeUtil.AddBusinessDays(srcDate, 10, GetHolidays(2019, "IT"));

Add 10 business days (skipping saturday, sunday, all italian holidays and the Rome-specific holidays for 2019)

var dtResult = DateTimeUtil.AddBusinessDays(srcDate, 10, GetHolidays(2019, "IT", "Rome"));

The above functions and code examples are further explained in this post of my blog.

Solution 9 - C#

Ok so this solution is slightly different (has some good and bad points):

  1. Solves weekends depending on the country (i.e. Arab countries have Friday-Saturday weekends)
  2. Depends on external library https://www.nuget.org/packages/Nager.Date/
  3. Only deals with adding business days
  4. Skips holidays as well (this can be removed)
  5. Uses recursion
public static class DateTimeExtensions
{
    public static DateTime AddBusinessDays(this DateTime date, int days, CountryCode countryCode)
    {
        if (days < 0)
        {
            throw new ArgumentException("days cannot be negative", "days");
        }

        if (days == 0)
        {
            return date;
        }

        date = date.AddDays(1);

        if (DateSystem.IsWeekend(date, countryCode) || DateSystem.IsPublicHoliday(date, countryCode))
        {
            return date.AddBusinessDays(days, countryCode);
        }

        days -= 1;

        return date.AddBusinessDays(days, countryCode);
    }
}

Usage:

[TestFixture]
public class BusinessDaysTests
{
    [TestCase("2021-06-04", 5, "2021-06-11", Nager.Date.CountryCode.GB)]
    [TestCase("2021-06-04", 6, "2021-06-14", Nager.Date.CountryCode.GB)]
    [TestCase("2021-05-28", 6, "2021-06-08", Nager.Date.CountryCode.GB)] // UK holidays 2021-05-31
    [TestCase("2021-06-01", 3, "2021-06-06", Nager.Date.CountryCode.KW)] // Friday-Saturday weekend in Kuwait
    public void AddTests(DateTime initDate, int delayDays, DateTime expectedDate, Nager.Date.CountryCode countryCode)
    {
        var outputDate = initDate.AddBusinessDays(delayDays, countryCode);
        Assert.AreEqual(expectedDate, outputDate);
    }
}

Solution 10 - C#

    public static DateTime AddBusinessDays(DateTime date, int days)
    {
        if (days == 0) return date;
        int i = 0;
        while (i < days)
        {
            if (!(date.DayOfWeek == DayOfWeek.Saturday ||  date.DayOfWeek == DayOfWeek.Sunday)) i++;  
            date = date.AddDays(1);
        }
        return date;
    }

Solution 11 - C#

I wanted an "AddBusinessDays" that supported negative numbers of days to add, and I ended up with this:

// 0 == Monday, 6 == Sunday
private static int epochDayToDayOfWeek0Based(long epochDay) {
    return (int)Math.floorMod(epochDay + 3, 7);
}

public static int daysBetween(long fromEpochDay, long toEpochDay) {
    // http://stackoverflow.com/questions/1617049/calculate-the-number-of-business-days-between-two-dates
    final int fromDOW = epochDayToDayOfWeek0Based(fromEpochDay);
    final int toDOW = epochDayToDayOfWeek0Based(toEpochDay);
    long calcBusinessDays = ((toEpochDay - fromEpochDay) * 5 + (toDOW - fromDOW) * 2) / 7;

    if (toDOW   == 6) calcBusinessDays -= 1;
    if (fromDOW == 6) calcBusinessDays += 1;
    return (int)calcBusinessDays;
}

public static long addDays(long epochDay, int n) {
    // https://alecpojidaev.wordpress.com/2009/10/29/work-days-calculation-with-c/
    // NB: in .NET, Sunday == 0, but in our code Monday == 0
    final int dow = (epochDayToDayOfWeek0Based(epochDay) + 1) % 7;
    final int wds = n + (dow == 0 ? 1 : dow); // Adjusted number of working days to add, given that we now start from the immediately preceding Sunday
    final int wends = n < 0 ? ((wds - 5) / 5) * 2
                            : (wds / 5) * 2 - (wds % 5 == 0 ? 2 : 0);
    return epochDay - dow + // Find the immediately preceding Sunday
           wds +            // Add computed working days
           wends;           // Add weekends that occur within each complete working week
}

No loop required, so it should be reasonably fast even for "big" additions.

It works with days expressed as a number of calendar days since the epoch, since that's exposed by the new JDK8 LocalDate class and I was working in Java. Should be simple to adapt to other settings though.

The fundamental properties are that addDays always returns a weekday, and that for all d and n, daysBetween(d, addDays(d, n)) == n

Note that theoretically speaking adding 0 days and subtracting 0 days should be different operations (if your date is a Sunday, adding 0 days should take you to Monday, and subtracting 0 days should take you to Friday). Since there's no such thing as negative 0 (outside of floating point!), I've chosen to interpret an argument n=0 as meaning add zero days.

Solution 12 - C#

I believe this could be a simpler way to GetBusinessDays:

    public int GetBusinessDays(DateTime start, DateTime end, params DateTime[] bankHolidays)
    {
        int tld = (int)((end - start).TotalDays) + 1; //including end day
        int not_buss_day = 2 * (tld / 7); //Saturday and Sunday
        int rest = tld % 7; //rest.
        
        if (rest > 0)
        {
            int tmp = (int)start.DayOfWeek - 1 + rest;
            if (tmp == 6 || start.DayOfWeek == DayOfWeek.Sunday) not_buss_day++; else if (tmp > 6) not_buss_day += 2;
        }

        foreach (DateTime bankHoliday in bankHolidays)
        {
            DateTime bh = bankHoliday.Date;
            if (!(bh.DayOfWeek == DayOfWeek.Saturday || bh.DayOfWeek == DayOfWeek.Sunday) && (start <= bh && bh <= end))
            {
                not_buss_day++;
            }
        }
        return tld - not_buss_day;
    }

Solution 13 - C#

Here is my code with both departure date, and delivery date at customer.

            // Calculate departure date
            TimeSpan DeliveryTime = new TimeSpan(14, 30, 0); 
            TimeSpan now = DateTime.Now.TimeOfDay;
            DateTime dt = DateTime.Now;
            if (dt.TimeOfDay > DeliveryTime) dt = dt.AddDays(1);
            if (dt.DayOfWeek == DayOfWeek.Saturday) dt = dt.AddDays(1);
            if (dt.DayOfWeek == DayOfWeek.Sunday) dt = dt.AddDays(1);
            dt = dt.Date + DeliveryTime;
            string DepartureDay = "today at "+dt.ToString("HH:mm");
            if (dt.Day!=DateTime.Now.Day)
            {
                DepartureDay = dt.ToString("dddd at HH:mm", new CultureInfo(WebContextState.CurrentUICulture));
            }
            Return DepartureDay;

            // Caclulate delivery date
            dt = dt.AddDays(1);
            if (dt.DayOfWeek == DayOfWeek.Saturday) dt = dt.AddDays(1);
            if (dt.DayOfWeek == DayOfWeek.Sunday) dt = dt.AddDays(1);
            string DeliveryDay = dt.ToString("dddd", new CultureInfo(WebContextState.CurrentUICulture));
            return DeliveryDay;

Solution 14 - C#

public static DateTime AddWorkingDays(this DateTime date, int daysToAdd)
{
    while (daysToAdd > 0)
    {
        date = date.AddDays(1);

        if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
        {
            daysToAdd -= 1;
        }
    }

    return date;
}

Solution 15 - C#

public static int GetBusinessDays(this DateTime start, DateTime end)
            {
                return Enumerable.Range(0, (end- start).Days)
                                .Select(a => start.AddDays(a))
                                .Where(a => a.DayOfWeek != DayOfWeek.Sunday)
                                .Where(a => a.DayOfWeek != DayOfWeek.Saturday)
                                .Count();
    
            }

Solution 16 - C#

Hope this helps someone.

private DateTime AddWorkingDays(DateTime addToDate, int numberofDays)
    {
        addToDate= addToDate.AddDays(numberofDays);
        while (addToDate.DayOfWeek == DayOfWeek.Saturday || addToDate.DayOfWeek == DayOfWeek.Sunday)
        {
            addToDate= addToDate.AddDays(1);
        }
        return addToDate;
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdrian ZanescuView Question on Stackoverflow
Solution 1 - C#Patrick McDonaldView Answer on Stackoverflow
Solution 2 - C#SimonView Answer on Stackoverflow
Solution 3 - C#ArjenView Answer on Stackoverflow
Solution 4 - C#Hugo YatesView Answer on Stackoverflow
Solution 5 - C#LukeHView Answer on Stackoverflow
Solution 6 - C#Jamie IdeView Answer on Stackoverflow
Solution 7 - C#BonelessView Answer on Stackoverflow
Solution 8 - C#DarksealView Answer on Stackoverflow
Solution 9 - C#Artur KędziorView Answer on Stackoverflow
Solution 10 - C#AlexView Answer on Stackoverflow
Solution 11 - C#Max BolingbrokeView Answer on Stackoverflow
Solution 12 - C#Carlos.CândidoView Answer on Stackoverflow
Solution 13 - C#JanBorupView Answer on Stackoverflow
Solution 14 - C#tocquevilleView Answer on Stackoverflow
Solution 15 - C#Kokul JoseView Answer on Stackoverflow
Solution 16 - C#user2686690View Answer on Stackoverflow