9 Stimmen

Wie berechne ich die Anzahl der Tage, abzüglich der Sonntage, zwischen zwei Daten in C#?

Ich bin dabei, ein Bibliotheksverwaltungssystem zu erstellen.

Ich habe den Zeitstempel verwendet, um die Datumsdifferenz zu berechnen, und mit Hilfe der Datumsdifferenz berechne ich auch das Fine.

Diese Datumsdifferenz umfasst nun alle Tage einer Woche. Bei einer Bibliotheksanwendung sollte die Geldstrafe jedoch nur für 6 Tage (Mo - Sa) in der Woche berechnet werden.

Ich bin nicht in der Lage, dies zu tun.

Kann mir jemand bei der Durchführung dieser Aufgabe helfen?

Vielen Dank im Voraus!!

17voto

Paul Sonier Punkte 37609

Im Wesentlichen können Sie die Rohzahl der Tage berechnen; Sie müssen die Anzahl der Sonntage ermitteln, die von dieser Zahl abgezogen werden müssen. Da Sie wissen, dass alle 7 Tage ein Sonntag ist, können Sie Ihre Rohzahl der Tage durch 7 teilen und diese Zahl von Ihrer Rohzahl der Tage abziehen. Nun müssen Sie die Anzahl der Sonntage in der verbleibenden Woche abziehen, die es gibt; a mod der rohen Anzahl der Tage gibt Ihnen die verbleibenden Tage an. Um herauszufinden, ob diese Zeitspanne einen Sonntag enthält, müssen Sie den Wochentag des ersten Tages kennen. Wenn Sie den Montag als 0, den Dienstag als 1, den Mittwoch als 3 usw. definieren, dann addieren Sie den Wert des Wochentags am Anfang der Zeitspanne zum Mod (7) der Rohanzahl der Tage, und wenn die Zahl 6 oder größer ist, haben Sie einen zusätzlichen Sonntag überbrückt und sollten 1 Tag von Ihrer Feinzahl abziehen.

In Pseudocode:

int fine;
int numdays =  endDay - startDay;

fine = numdays - (numdays / 7);

int dayOfWeek = startDate.DayOfWeek;
if (dayOfWeek + (numdays % 7) > 6)
{
   fine = fine - 1;
}

7voto

raven Punkte 17587

Das wird genügen:

private int DaysLate(DateTime dueDate, DateTime returnDate)
{
    var ts = returnDate - dueDate;
    int dayCount = 0;

    for (int i = 1; i <= ts.Days; i++)
    {
        if (dueDate.AddDays(i).DayOfWeek != DayOfWeek.Sunday)
            dayCount++;
    }

    return dayCount;
}

2voto

Andriy Volkov Punkte 18140

Basierend auf der Antwort von Jacob Proffitt, aber ohne den Overhead der In-Memory-Liste. Da DaysBetween seine Daten dynamisch liefert, wird die Anzahl berechnet, wenn die Liste generiert wird:

int c = DaysBetween(begin, end).Count(d => d.DayOfWeek != DayOfWeek.Sunday);

private IEnumerable<DateTime> DaysBetween(DateTime begin, DateTime end)
{
    for(var d = begin; d <= end; d.AddDays(1)) yield return d;
}

Wenn Sie LINQ nicht zur Schau stellen wollten, könnten Sie es natürlich vereinfachen und mit einer Funktion arbeiten:

private int DaysBetween(DateTime begin, DateTime end)
{
    int count = 0;
    for(var d = begin; d <= end; d.AddDays(1)) 
       if(d.DayOfWeek != DayOfWeek.Sunday) count++
    return count;
}

IMHO sind beide sauberer und einfacher zu verstehen, zu debuggen, Fehler zu beheben und zu modifizieren als der Favorit von allen (die Antwort von Rabe).

Natürlich ist dies eine O(n)-Lösung, d. h. je weiter die Tage auseinander liegen, desto länger dauert die Berechnung. Während dies für die meisten Anwendungen in der realen Welt in Ordnung ist, können Sie in einigen Fällen einen formelbasierten Ansatz bevorzugen, etwa in dieser Form:

int q = end.Subtract(begin).Days - (end.Subtract(begin).Days / 7);

1voto

Dies wurde schnell getestet und scheint für Ihre Zwecke zu funktionieren:(edit: einige Kommentare zur Klarheit hinzugefügt und Codefehler korrigiert)

private static int CalculateDaysToFine(DateTime dateDue, DateTime dateIn)
        {
            TimeSpan ts = dateIn - dateDue;
            int daysToFine = ts.Days - (ts.Days/7); //subtract full weeks (1 Sunday each)
            if (((int)dateDue.DayOfWeek + (ts.Days%7)) >6) //check to see if the remaining days contain a Sunday
                daysToFine--;
            return daysToFine;
        }

0voto

Malcolm Punkte 400

Hier ist meine Umsetzung. Mein Ziel war O(1) Ausführungszeit mit einem ähnlichen Ansatz wie McWafflestix. Ich habe versucht, es lesbar zu halten, den OO-Code zu maximieren und die "mathematische Magie" so weit wie möglich zu minimieren (nicht, dass ich etwas gegen Mathematik hätte... oder gegen Magie).

Die Idee ist, die Anzahl der vollständigen 7-Tage-Wochen zwischen dem Fälligkeitsdatum und dem Rückgabedatum zu ermitteln und eine "Delta"-Anzahl von Tagen zu bestimmen, um die die Zahl korrigiert wird. Solange Sie garantieren können, dass weder das Fälligkeitsdatum noch das Rückgabedatum auf einen Sonntag fallen (was nach Ihrer Beschreibung kein Problem sein dürfte), wird dies wie erwartet funktionieren.

        static int CalculateFineDays(DateTime due, DateTime returned)
        {
            TimeSpan ts = returned - due;
            if (ts < TimeSpan.Zero)
                return 0;
            int delta = returned.DayOfWeek - due.DayOfWeek;
            return delta + ts.Subtract(TimeSpan.FromDays(delta)).Days * 6 / 7;
        }

Edit: Ich hatte bereits eine Lösung vorgeschlagen und einen Fehler darin gefunden, und als ich daran arbeitete, reduzierte ich den Code auf dies.

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