代码之家  ›  专栏  ›  技术社区  ›  Adrian Zanescu

AddBusinessDays和GetBusinessDays

  •  81
  • Adrian Zanescu  · 技术社区  · 17 年前

    我需要找到2个优雅的完整实现

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

    编辑: 我所说的工作日是指工作日(星期一、星期二、星期三、星期四、星期五)。没有假期,周末除外。

    我已经有了一些丑陋的解决方案,但我想知道是否有优雅的方法可以做到这一点。谢谢


    这是我到目前为止写的。它在所有情况下都有效,也会产生负面影响。 仍然需要GetBusinessDays实现

    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);
    }
    
    14 回复  |  直到 9 年前
        1
  •  138
  •   Patrick McDonald    12 年前

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

    第二个功能GetBusinessDays可以按如下方式实现:

    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;
        }
    }
    
        2
  •  66
  •   Simon Randy Burden    12 年前

    使用 Fluent DateTime

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

    内部代码如下

        /// <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);
        }
    
        3
  •  15
  •   Arjen    13 年前

    使用负数的工作日进行减去。我认为这是一个相当优雅的解决方案。它似乎在所有情况下都有效。

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

    例子:

    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();
            }
        }
    }
    
        4
  •  9
  •   Hugo Yates    11 年前

    例如:

    • 周三-3个工作日=上周五
    • 周五-7个工作日=上周三
    • 周二-5个工作日=上周二

    好吧,你明白了;)

    最后我写了这个扩展类

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

    它使用了我认为在其他地方有用的方法。。。

    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 (MyClass.IsBusinessDay(date)) 如果 if ((date.DayOfWeek != DayOfWeek.Saturday) && (date.DayOfWeek != DayOfWeek.Sunday))

    所以现在你可以做了

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

    或

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

    以下是一些测试的结果:

    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
    
        5
  •  2
  •   LukeH    17 年前
    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);
    }
    
        6
  •  1
  •   Boneless    10 年前

    我来晚了,但我做了一个小图书馆,里面有在工作日进行简单操作所需的所有定制。。。我把它留在这里: Working Days Management

        7
  •  1
  •   bytecode77    10 年前

    唯一真正的解决方案是让这些调用访问定义业务日历的数据库表。您可以将其编码为周一到周五的工作周,而不会有太多困难,但处理假期将是一项挑战。

    编辑以添加非优雅和未经测试的部分解决方案:

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

    我还违反了无循环要求。

        8
  •  1
  •   Darkseal    7 年前

    我之所以重新发布这篇文章,是因为今天我必须找到一种方法来排除 和 星期日

    • 国家固定假日(至少对于西方国家,如2001年1月)。
    • 计算假期(如复活节和复活节星期一)。
    • 国家特定假日(如意大利解放日或美国ID4)。
    • 特定于城镇的假日(如罗马圣守护神日)。
    • 任何其他定制假日(如“明天我们的办公室将关闭”)。

    最后,我提出了以下一组帮助器/扩展类:尽管它们并不十分优雅,因为它们大量使用了非有效循环,但它们足够好,可以永远解决我的问题。我在这篇文章中删除了全部源代码,希望它对其他人也有用。

    源代码

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

    这段代码很容易解释,但是这里有几个例子来解释如何使用它。

    增加10个工作日(仅跳过周六和周日工作日)

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

    增加10个工作日(跳过2019年的周六、周日和所有国家/地区固定假日)

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

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

    增加10个工作日(跳过2019年的周六、周日、所有意大利假日和罗马特定假日)

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

    进一步解释了上述函数和代码示例 in this post 我的博客。

        9
  •  1
  •   Artur Kedzior    5 年前

    好的,这个解决方案略有不同(有一些优点和缺点):

    1. https://www.nuget.org/packages/Nager.Date/
    2. 只涉及增加营业日
    3. 也跳过假期(可以删除)
    4. 使用递归
    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);
        }
    }
    

    用法:

    [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);
        }
    }
    
        10
  •  0
  •   Alex    13 年前
        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;
        }
    
        11
  •  0
  •   Max Bolingbroke    10 年前

    我想要一个“AddBusinessDays”,支持负数的天数添加,结果是:

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

    它适用于自纪元以来以日历天数表示的天数,因为这是由新的JDK8 LocalDate类公开的,而我是在Java中工作的。但是应该很容易适应其他设置。

    其基本性质是 addDays 总是返回一个工作日,这对所有 d 和 n , daysBetween(d, addDays(d, n)) == n

    请注意,从理论上讲,加0天和减0天应该是不同的操作(如果您的日期是星期天,则加0天应带您到星期一,减0天应带您到星期五)。因为不存在负0(浮点之外!),所以我选择将参数n=0解释为意义 零天。

        12
  •  0
  •   Carlos.Cândido    10 年前

    我相信这可能是一种更简单的获取工作日的方式:

        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;
        }
    
        13
  •  0
  •   JanBorup    9 年前

    这是我的代码,包括出发日期和客户的交货日期。

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

    快乐编码。

        14
  •  0
  •   Franc    9 年前
    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;
    }
    
        15
  •  0
  •   Kokul Jose    6 年前
    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();
        
                }
    
        16
  •  -1
  •   user2686690    13 年前

    希望这对别人有帮助。

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