36 Stimmen

Hinzufügen von Tagen zu einem Datum, aber Ausschluss von Wochenenden

Wie kann ich zu einem Datum eine Anzahl von Tagen hinzufügen, aber die Wochenenden ausschließen? Wenn ich zum Beispiel den 12.11.2008 (Mittwoch) eingebe und fünf addiere, ergibt das den 19.11.2008 (Mittwoch) und nicht den 17.11.2008 (Montag).

Ich kann mir eine einfache Lösung vorstellen, wie das Durchlaufen einer Schleife für jeden hinzuzufügenden Tag und das Überprüfen, ob es ein Wochenende ist, aber ich würde gerne sehen, ob es etwas Eleganteres gibt. Ich würde auch in jeder F#-Lösung interessiert sein.

0 Stimmen

Werden Sie eine kleine Anzahl von Tagen oder Millionen von Tagen hinzufügen?

10 Stimmen

Ich will Ihnen nur sagen: Sobald Sie ihnen sagen, dass es kein Problem ist, die Wochenenden auszuschließen, werden sie auch Urlaub machen wollen. Denken Sie darüber nach, bevor Sie etwas einführen.

0 Stimmen

Es gibt eine Bibliothek auf NuGet namens TimePeriodLibrary.NET von Jani Giannoudis, die eine enorme Menge an Funktionalität für diese Art von Berechnungen bietet. Wenn sie später auch Feiertage haben wollen, wird es einfach sein.

5voto

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

Die Anzahl der "echten" Tage, die hinzugefügt werden müssen, ist die Anzahl der Wochentage, die Sie angeben, plus die Anzahl der kompletten Wochen, die in dieser Summe enthalten sind (daher weekDaysToAdd / 5) mal zwei (zwei Tage am Wochenende); plus ein möglicher Versatz von zwei Tagen, wenn der ursprüngliche Wochentag plus die Anzahl der hinzuzufügenden Wochentage "innerhalb" der Woche (daher weekDaysToAdd mod 5) größer oder gleich 5 ist (d. h. ein Wochenendtag ist).

Hinweis: Dies funktioniert unter der Annahme, dass 0 = Montag, 2 = Dienstag, ... 6 = Sonntag. Außerdem funktioniert dies nicht bei negativen Wochentagsintervallen.

1voto

F#-Geschmack von http://stackoverflow.com/questions/1044688 die Antwort:

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

0voto

ElmerMiller Punkte 399

Dies ist besser, wenn jemand auf der Suche nach einem TSQL Lösung. Eine Zeile Code und funktioniert mit Negativen.

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

0voto

Mark Worrall Punkte 244

Ich habe es folgendermaßen gemacht.

Ich musste die Fälligkeitstermine der SLA (Service Level Agreement) auf der Grundlage eines Startdatums und einer Anzahl von Tagen berechnen und dabei Wochenenden und Feiertage berücksichtigen:

    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() ist eine im Speicher zwischengespeicherte Liste der Feiertage.

(Anmerkung: dies ist eine gekürzte Version für die öffentliche Weitergabe, es gibt einen Grund, warum es keine Erweiterungsmethode ist)

0voto

Joerg Punkte 1
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);
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X