2008-11-10 17 views
19

Podano datę, jak dodać do niej liczbę dni, ale nie wliczam weekendu. Na przykład, biorąc pod uwagę datę 11.12.2008 (środa) i dodanie pięciu, nastąpi 11/19/2008 (środa), a nie 11/17/2008 (poniedziałek).Dodawanie dni do daty, ale z wyłączeniem weekendów

Mogę wymyślić proste rozwiązanie, takie jak zapętlenie każdego dnia, aby dodać i sprawdzić, czy jest weekend, ale chciałbym zobaczyć, czy jest coś bardziej eleganckiego. Byłbym też zainteresowany dowolnym rozwiązaniem F #.

+0

Czy zamierzasz być dodanie małej ilości dni lub milionach dni? – LeppyR64

+7

Po prostu informuję - gdy tylko im powiesz, że z wyłączeniem weekendów nie ma problemu, oni też będą chcieli wakacji. Pomyśl o tym, zanim zaimplementujesz cokolwiek. – dnord

Odpowiedz

-2

Biorąc pod uwagę liczbę oryginalnego dzień w roku D i oryginalnym dzień w tygodniu W i liczby dni roboczych, aby dodać N, kolejny numer dnia tygodnia jest

W + N % 5. 

Następnego dnia w roku (bez sprawdzania obejścia) jest

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

Przyjmuje to, że masz dzielenie liczby całkowitej.

+0

Dlaczego głosowanie w dół? Czy to daje nieprawidłowy wynik? – DOK

+0

Nie widzę żadnej oczywistej wady z moją odpowiedzią. Pozostawienie komentarza mówiącego, co jest nie tak, byłoby pomocne. – gnud

+0

Nie spadłem, ale kilka osób zasugerowało ten algorytm i wygląda na to, że jest mi źle. Co stanie się, gdy dodasz 1 dzień roboczy do piątku? 'n/5 * 7' wynosi zero, a' n% 5' to jeden, więc dodajesz jedną i dostajesz sobotę, ale prawidłową odpowiedzią jest poniedziałek. –

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

Może to być zamierzone dla twojego scenariusza, ale dla jakichkolwiek dat wprowadzonych w piątek sobotę lub niedzielę nie są obliczane poprawnie. Komentarz Marco M. będzie na to działać. – Frazer

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

Mianowicie; liczba dni "rzeczywistych" do dodania to liczba dni tygodnia, które określasz, oraz liczba pełnych tygodni, które są w tej sumie (stąd TydzieńDodajDodaj/5) razy dwa (dwa dni w weekend); plus potencjalne przesunięcie o dwa dni, jeśli pierwotny dzień tygodnia plus liczba dni tygodnia dodawania "w ciągu tygodnia" (stąd "Dodaj tydzień") jest większy lub równy 5 (tj. jest dniem weekendowym).

Uwaga: działa to przy założeniu, że 0 = poniedziałek, 2 = wtorek, ... 6 = niedziela. Również; to nie działa w ujemnych odstępach w dni robocze.

-1

wzór będą: Workday (data, ilosc dni (dni tygodnia (1)))

Spróbuj. To pomoże.

0

Utworzono rozszerzenie, które umożliwia dodawanie lub odejmowanie dni roboczych. Użyj ujemnej liczby dni roboczych do odjęcia. Wydaje się, że działa we wszystkich przypadkach.

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

przykład:

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

To rozwiązanie dokładnie zakłada, że ​​jeśli data źródłowa jest weekendem, dodanie lub odjęcie 1 pozwoli na przejście jednego dnia tygodnia, w wyniku odpowiednio we wtorek lub czwartek. Plus zero zwróci poniedziałek. Bardzo wydajny, bez konieczności wykonywania powtórzeń/pętli. Dzięki! – Heliac

0

Jest lepiej, jeśli ktoś patrzy do roztworu TSQL. Jedna linia kodu i działa z wykluczeniami.

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

bez nadmiernego komplikowania algorytm, można po prostu utworzyć metodę rozszerzenia takiego:

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

Powoduje nieskończoną pętlę, jeśli dodasz ujemną liczbę dni. – Jules

+0

Prawda. Zobacz odpowiedź Ogglasa na lepszą wersję tego – tocqueville

2

chciałbym używać tego rozszerzenia, należy pamiętać, ponieważ jest to metoda rozszerzenie, aby umieścić go w statycznym klasa.

Zastosowanie:

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

Kod:

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

Szkoda, że ​​nie łączysz się z biblioteką FluentDateTime zamiast kopiować-wklejając kod (https://github.com/FluentDateTime/FluentDateTime/blob/master/FluentDateTime/DateTime/ DateTimeExtensions.cs). Daj oryginałowi trochę kredytu! – Jules

+0

@Jules Dzięki, zapomniałem dodać link! – Ogglas