2008-11-10 148 views
19

給定一個日期,我怎樣才能給它添加幾天,但排除週末。例如,2008年12月11日(星期三)和2008年11月19日(星期三),而不是2008年11月17日(星期一)增加5。將日期添加到日期但不包括週末

我可以想到一個簡單的解決方案,比如每天循環添加並檢查是否是週末,但我想看看是否有更優雅的東西。我也會對任何F#解決方案感興趣。

+0

你要增加一個小的天數天或數以百萬計的? – LeppyR64 2008-11-10 21:51:58

+7

只是讓你知道 - 只要你告訴他們週末不包括週末是沒有問題的,他們也會想要假期。在實施任何事情之前考慮一下。 – dnord 2008-11-10 22:12:49

回答

-2

由於原來一天的一年d和原日的一週W和工作日天數的數量增加N,接下來的工作日數爲

W + N % 5. 

第二天在今年(沒有環繞檢查)是

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

這是假設你有整數除法。

+0

爲什麼倒票?這會產生一個不正確的結果嗎? – DOK 2008-11-10 22:33:27

+0

我的答案沒有看到任何明顯的缺陷。留下評論說什麼是錯的會有所幫助。 – gnud 2008-11-11 01:07:33

+0

我沒有downvote,但有幾個人建議這種算法,它看起來不對我。當您將一個工作日添加到星期五會發生什麼? `n/5 * 7`是零,`n%5`是一個,所以你加一個並得到一個星期六,但正確的答案是星期一。 – 2011-03-26 10:15:20

6
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); 
} 
+0

對於您的情況可能有意爲之,但對於週五週六或週日輸入的任何日期計算不正確。 Marco M.評論將爲此工作。 – Frazer 2017-01-20 12:44:39

3
int daysToAdd = weekDaysToAdd + ((weekDaysToAdd/5) * 2) + (((origDate.DOW + (weekDaysToAdd % 5)) >= 5) ? 2 : 0); 

要機智要添加的「真實」天數是您指定的平日數,加上總數(因此爲weekDaysToAdd/5)乘以兩(週末兩天)的完整星期數;如果一週的原始星期加上星期內添加「星期內」(因此星期幾加入模5)大於或等於5(即週末日)的數量,則加上兩天的潛在偏移。

注意:假設0 =星期一,2 =星期二,... 6 =星期天,也;這不適用於負週日的時間間隔。

-1

公式爲:工作日(日,節數天(工作日(1)))

試試這個。這將有所幫助。

0

我創建了一個擴展,允許您添加或減少工作日。 使用負數的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(); 
     } 
    } 
} 
0

這是更好,如果有人正在尋找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)[email protected])/5)*2*SIGN(@n)[email protected]/7,@Date)END 
3

沒有過於複雜的算法,你可以只創建一個擴展方法是這樣的:因爲它是一個擴展方法來把它放在一個靜態

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

我會使用這個擴展,記得類。

用法:

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; 
     } 
    } 
} 
相關問題