简体   繁体   English

向日期添加天数但不包括周末

[英]Adding Days to a Date but Excluding Weekends

Given a date how can I add a number of days to it, but exclude weekends.给定一个日期,我如何为其添加天数,但不包括周末。 For example, given 11/12/2008 (Wednesday) and adding five will result in 11/19/2008 (Wednesday) rather than 11/17/2008 (Monday).例如,给定 11/12/2008(星期三)并添加五个将导致 11/19/2008(星期三)而不是 11/17/2008(星期一)。

I can think of a simple solution like looping through each day to add and checking to see if it is a weekend, but I'd like to see if there is something more elegant.我可以想到一个简单的解决方案,比如每天循环添加并检查是否是周末,但我想看看是否有更优雅的东西。 I'd also be interested in any F# solution.我也对任何 F# 解决方案感兴趣。

使用 Fluent DateTime https://github.com/FluentDateTime/FluentDateTime

var dateTime = DateTime.Now.AddBusinessDays(4);
public DateTime AddBusinessDays(DateTime dt, int nDays)
{
    int weeks = nDays / 5;
    nDays %= 5;
    while(dt.DayOfWeek == DayOfWeek.Saturday || dt.DayOfWeek == DayOfWeek.Sunday)
        dt = dt.AddDays(1);

    while (nDays-- > 0)
    {
        dt = dt.AddDays(1);
        if (dt.DayOfWeek == DayOfWeek.Saturday)
            dt = dt.AddDays(2);
    }
    return dt.AddDays(weeks*7);
}

Without over-complicating the algorithm, you could just create an extension method like this:在不使算法过于复杂的情况下,您可以创建一个像这样的扩展方法:

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;
}
int daysToAdd = weekDaysToAdd + ((weekDaysToAdd / 5) * 2) + (((origDate.DOW + (weekDaysToAdd % 5)) >= 5) ? 2 : 0);

To wit;以机智; the number of "real" days to add is the number of weekdays you're specifying, plus the number of complete weeks that are in that total (hence the weekDaysToAdd / 5) times two (two days in the weekend);要添加的“实际”天数是您指定的工作日数,加上该总数中的完整周数(因此为 weekDaysToAdd / 5)乘以 2(周末两天); plus a potential offset of two days if the original day of the week plus the number of weekdays to add "within" the week (hence the weekDaysToAdd mod 5) is greater than or equal to 5 (ie is a weekend day).如果一周中的原始日期加上一周“内”添加的工作日数(因此 weekDaysToAdd mod 5)大于或等于 5(即是周末日),则加上两天的潜在偏移量。

Note: this works assuming that 0 = Monday, 2 = Tuesday, ... 6 = Sunday.注意:这假设 0 = 星期一,2 = 星期二,... 6 = 星期日。 Also;还; this does not work on negative weekday intervals.这不适用于负的工作日间隔。

I would use this extension, remember since it is an extension method to put it in a static class.我会使用这个扩展,记住因为它是一个将它放在静态类中的扩展方法。

Usage:用法:

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

Code:代码:

namespace ExtensionMethods
{
    public static class MyExtensionMethods
    {
        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;
        }
    }
}

Source:来源:

https://github.com/FluentDateTime/FluentDateTime/blob/master/src/FluentDateTime/DateTime/DateTimeExtensions.cs https://github.com/FluentDateTime/FluentDateTime/blob/master/src/FluentDateTime/DateTime/DateTimeExtensions.cs

I created an extension that allows you to add or subtract business days.我创建了一个扩展程序,允许您增加或减少工作日。 Use a negative number of businessDays to subtract.使用负数的工作日来减去。 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();
        }
    }
}

F# flavor of http://stackoverflow.com/questions/1044688 's answer: http://stackoverflow.com/questions/1044688答案的 F# 风格:

namespace FSharpBasics

module BusinessDays =

    open System;

    let private weekLength = 5

    (*operation*)
    let addBusinessDays (numberOfBusinessDays: int) (startDate: DateTime) =
        let startWeekDay = startDate.DayOfWeek
        let sign = Math.Sign(numberOfBusinessDays) 
        let weekendSlide, businessDaysSlide = 
            match startWeekDay with
            | DayOfWeek.Saturday when sign > 0 -> (2, -1)
            | DayOfWeek.Saturday when sign < 0 -> (-1, 1)   
            | DayOfWeek.Sunday when sign > 0 -> (1, -1)
            | DayOfWeek.Sunday when sign < 0 -> (-2, 1)
            | _ -> (0, 0)
        let baseStartDate = startDate.AddDays (float weekendSlide)        
        let days = Math.Abs (numberOfBusinessDays + businessDaysSlide) % weekLength
        let weeks = Math.Abs (numberOfBusinessDays + businessDaysSlide) / weekLength
        let baseWeekDay = int baseStartDate.DayOfWeek
        let oneMoreWeekend =
            if sign = 1 && days + baseWeekDay > 5 || sign = -1 && days >= baseWeekDay then 2
            else 0
        let totalDays = (weeks * 7) + days + oneMoreWeekend
        baseStartDate.AddDays (float totalDays)

    [<EntryPoint>]
    let main argv =
        let now = DateTime.Now 
        printfn "Now is %A" now
        printfn "13 business days from now would be %A" (addBusinessDays 13 now)
        System.Console.ReadLine() |> ignore
        0 

This is better if anyone is looking for a TSQL solution.如果有人正在寻找TSQL解决方案,这会更好。 One line of code and works with negatives.一行代码并处理底片。

CREATE FUNCTION[dbo].[AddBusinessDays](@Date date,@n INT)RETURNS DATE AS BEGIN 
DECLARE @d INT;SET @d=4-SIGN(@n)*(4-DATEPART(DW,@Date));
RETURN DATEADD(D,@n+((ABS(@n)+@d-2)/5)*2*SIGN(@n)-@d/7,@Date)END

Here is how I did it.这是我如何做到的。

I had to calculate SLA (Service Level Agreement) due dates based on a start date and number of days, and account for weekends and public holidays:我必须根据开始日期和天数计算 SLA(服务水平协议)到期日,并考虑周末和公共假期:

    public DateTime? CalculateSLADueDate(DateTime slaStartDateUTC, double slaDays)
    {
        if (slaDays < 0)
        {
            return null;
        }

        var dayCount = slaDays;
        var dueDate = slaStartDateUTC;

        var blPublicHoliday = new PublicHoliday();
        IList<BusObj.PublicHoliday> publicHolidays = blPublicHoliday.SelectAll();

        do
        {
            dueDate = dueDate.AddDays(1);

            if ((dueDate.DayOfWeek != DayOfWeek.Saturday)
            && (dueDate.DayOfWeek != DayOfWeek.Sunday)
            && !publicHolidays.Any(x => x.HolidayDate == dueDate.Date))
            {
                dayCount--;
            }
        }
        while (dayCount > 0);

        return dueDate;
    }

blPublicHoliday.SelectAll() is a cached in-memory list of public holidays. blPublicHoliday.SelectAll() 是一个缓存在内存中的公共假期列表。

(note: this is a cut down version for sharing publicly, there is a reason its not an extension method) (注意:这是公开共享的缩减版本,它不是扩展方法是有原因的)

enter code public static DateTime AddWorkDays(DateTime dt,int daysToAdd)
    {
        int temp = daysToAdd;
        DateTime endDateOri = dt.AddDays(daysToAdd);
        while (temp !=0)
        {
            if ((dt.AddDays(temp).DayOfWeek == DayOfWeek.Saturday)|| (dt.AddDays(temp).DayOfWeek == DayOfWeek.Sunday))
            {
                daysToAdd++;
                temp--;
            }
            else
            {
                temp--;
            }
        }
        while (endDateOri.AddDays(temp) != dt.AddDays(daysToAdd))
        {
            if ((dt.AddDays(temp).DayOfWeek == DayOfWeek.Saturday) || (dt.AddDays(temp).DayOfWeek == DayOfWeek.Sunday))
            {
                daysToAdd++;
            }
            temp++;
        }
        // final enddate check
        if (dt.AddDays(daysToAdd).DayOfWeek == DayOfWeek.Saturday)
        {
            daysToAdd = daysToAdd + 2;
        }
        else if (dt.AddDays(daysToAdd).DayOfWeek == DayOfWeek.Sunday)
        {
            daysToAdd++;
        }
        return dt.AddDays(daysToAdd);
    }
DateTime oDate2 = DateTime.Now;

int days = 8;

for(int i = 1; i <= days; i++)
{
  if (oDate.DayOfWeek == DayOfWeek.Saturday) 
  {
    oDate = oDate.AddDays(2);
  }
  if (oDate.DayOfWeek == DayOfWeek.Sunday) 
  {
    oDate = oDate.AddDays(1);
  }
  oDate = oDate.AddDays(1);
}

Formula will be: Workday(date,no.of days,(weekday(1)))公式为:工作日(日期,天数,(工作日(1)))

Try this.尝试这个。 This will help.这会有所帮助。

Given the number of the original day in the year D and original day in the week W and the number of workdays to add N, the next weekday number is给定 D 年的原始天数和 W 周的原始天数,加上 N 的工作日数,下一个工作日数为

W + N % 5.

The next day in the year (with no wraparound check) is一年中的第二天(没有环绕检查)是

D + ((N / 5) * 7) + N % 5).

This is assuming that you have integer division.这是假设您有整数除法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 日期范围内的天数,不包括周末和其他日期,以 C# 为单位 - Number of days in date range, excluding weekends and other dates, in C# 倒计时到不包括周末和剩余假期的日期 - Countdown to a date excluding weekends and remaining holidays 在两个日期之间获取列出的日期,不包括mysql中的周末 - getting listed date between two dates excluding weekends in mysql 考虑到周末和节假日,增加迄今为止的工作日 - adding workdays to date taking into account weekends and holidays 是否有SSRS表达式可以计算两天之间的差异(周末,周六和周日除外)? - Is there an SSRS expression for calculating difference between two days excluding weekends, Saturday and Sunday? C# - 以天、小时和分钟计算 SLA,不包括非工作时间、周末和公共假期 - C# - calculate sla in days, hours and minutes excluding non working hours, weekends and public holidays 将特定日期从 CET 转换为 IST 并排除周末后,如何在给定特定日期的情况下获取目标日期 - How to get a target date given a specific date after converting specific date from CET to IST and excluding weekends 如何查找从给定日期和日期(不包括星期日)开始的结束日期 - How to find End date from the given date and days excluding sundays 如何在跳过周末和其他假期的同时向日期添加天数,开始日期是周末还是假期 - How to add a number of days to a Date while skipping weekends and other holidays and start day is weekend or holiday LINQ 不包括周末的列值总和 - LINQ sum of column values excluding weekends
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM