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

给定一个日期我如何添加一些天,但排除周末。 例如,给定2008年12月11日(星期三),并且在2008年11月19日(星期三)而不是2008年11月17日(星期一)增加5个。

我可以想到一个简单的解决方案,比如循环每天添加和检查是否是一个周末,但我想看看是否有更优雅的东西。 我也对任何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); } 

没有过度复杂的算法,你可以创建一个像这样的扩展方法:

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

以机智; 要添加的“实际”天数是指您指定的工作日数,加上该总数中的完整周数(因此为weekDaysToAdd / 5)乘以2(周末两天); 如果一周的原始日加上在一周内“添加”的工作日数(因此,weekDaysToAdd mod 5)大于或等于5(即周末日),则加上两天的潜在偏移量。

注意:这可以假设0 =星期一,2 =星期二,… 6 =星期日。 也; 这对于工作日的负面间隔不起作用。

我会使用这个扩展,记住,因为它是一个扩展方法,将它放在静态类中。

用法:

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

码:

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

我创建了一个扩展程序,允许您添加或减去工作日。 使用负数的businessDays进行减去。 它似乎适用于所有情况。

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

如果有人在寻找TSQL解决方案,这会更好。 一行代码和负面作品。

 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 

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) [] 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 

公式为:工作日(日期,天数,(工作日(1)))

试试这个。 这会有所帮助。

给定D年中原始日期的数量和W周中的原始日期以及添加N的工作日数,下一个工作日数量为

 W + N % 5. 

一年中的第二天(没有环绕检查)是

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

这假设你有整数除法。