Ich muss 2 elegante vollständige Implementierungen von finden
public static DateTime AddBusinessDays(this DateTime date, int days)
{
// code here
}
and
public static int GetBusinessDays(this DateTime start, DateTime end)
{
// code here
}
O (1) bevorzugt (keine Schleifen).
BEARBEITEN: Mit Werktagen meine ich Arbeitstage (Montag, Dienstag, Mittwoch, Donnerstag, Freitag). Keine Feiertage, nur Wochenenden ausgeschlossen.
Ich habe bereits einige hässliche Lösungen, die zu funktionieren scheinen, aber ich frage mich, ob es elegante Möglichkeiten gibt, dies zu tun. Vielen Dank
Das habe ich bisher geschrieben. Es funktioniert in allen Fällen und macht auch Negative. Benötigen Sie noch eine GetBusinessDays-Implementierung
public static DateTime AddBusinessDays(this DateTime startDate,
int businessDays)
{
int direction = Math.Sign(businessDays);
if(direction == 1)
{
if(startDate.DayOfWeek == DayOfWeek.Saturday)
{
startDate = startDate.AddDays(2);
businessDays = businessDays - 1;
}
else if(startDate.DayOfWeek == DayOfWeek.Sunday)
{
startDate = startDate.AddDays(1);
businessDays = businessDays - 1;
}
}
else
{
if(startDate.DayOfWeek == DayOfWeek.Saturday)
{
startDate = startDate.AddDays(-1);
businessDays = businessDays + 1;
}
else if(startDate.DayOfWeek == DayOfWeek.Sunday)
{
startDate = startDate.AddDays(-2);
businessDays = businessDays + 1;
}
}
int initialDayOfWeek = (int)startDate.DayOfWeek;
int weeksBase = Math.Abs(businessDays / 5);
int addDays = Math.Abs(businessDays % 5);
if((direction == 1 && addDays + initialDayOfWeek > 5) ||
(direction == -1 && addDays >= initialDayOfWeek))
{
addDays += 2;
}
int totalDays = (weeksBase * 7) + addDays;
return startDate.AddDays(totalDays * direction);
}
AddBusinessDays
Implementierung in der obigen Frage (die eigentlich eine gelöschte Antwort war, die ich zum Wiederherstellen vorgeschlagen habe; ein Mod hat diese Antwort stattdessen auf die Frage kopiert): Meiner Meinung nach ist diese Lösung besser als alle bisherigen Antworten, da sie die einzige ist eine, die mit negativen Werten korrekt umgeht, Samstag und Sonntag als Quelle und keine Drittanbieter-Bibliothek benötigt. (Ich habe ein kleines Programm erstellt, um die verschiedenen Lösungen hier zu testen.) Ich würde nurif (businessDays == 0) return startDate;
am Anfang der Methode hinzufügen , um auch für diesen Randfall das richtige Ergebnis zu erhalten.AddBusinessDays
die allgemeinste Lösung waren, die in allen von mir benötigten Fällen funktioniert hat. Ich habe es in eines meiner aktuellen Projekte kopiert (nach geringfügiger Änderung und Übersetzung in C ++), danke für den Code :) Es hat sehr geholfen, da es überraschend schwierig ist, alle Randfälle richtig zu machen.Antworten:
Letzter Versuch für Ihre erste Funktion:
Die zweite Funktion, GetBusinessDays, kann wie folgt implementiert werden:
quelle
mit Fluent DateTime :
Der interne Code lautet wie folgt
quelle
Ich habe eine Erweiterung erstellt, mit der Sie Werktage hinzufügen oder entfernen können. Verwenden Sie zum Subtrahieren eine negative Anzahl von businessDays. Ich denke, es ist eine ziemlich elegante Lösung. Es scheint in allen Fällen zu funktionieren.
Beispiel:
quelle
Für mich musste ich eine Lösung haben, die Wochenenden überspringt und entweder negativ oder positiv ist. Meine Kriterien waren, wenn es vorwärts ging und an einem Wochenende landete, würde es auf Montag vorrücken müssen. Wenn es zurückgehen und an einem Wochenende landen würde, müsste es auf Freitag springen.
Na du kommst auf die Idee;)
Am Ende habe ich diese Erweiterungsklasse geschrieben
Es verwendet diese Methode, von der ich dachte, dass sie nützlich wäre, um sie an anderer Stelle zu verwenden ...
Wenn Sie sich nicht darum kümmern möchten, können Sie es einfach durch
if (MyClass.IsBusinessDay(date))
if ersetzenif ((date.DayOfWeek != DayOfWeek.Saturday) && (date.DayOfWeek != DayOfWeek.Sunday))
Jetzt können Sie es also tun
oder
Hier sind die Ergebnisse einiger Tests:
quelle
quelle
Ich komme zu spät, um die Antwort zu erhalten, aber ich habe eine kleine Bibliothek mit allen Anpassungen erstellt, die für einfache Vorgänge an Arbeitstagen erforderlich sind ... Ich lasse es hier: Working Days Management
quelle
Die einzige echte Lösung besteht darin, dass diese Anrufe auf eine Datenbanktabelle zugreifen, die den Kalender für Ihr Unternehmen definiert. Sie könnten es für eine Arbeitswoche von Montag bis Freitag ohne allzu große Schwierigkeiten codieren, aber der Umgang mit Feiertagen wäre eine Herausforderung.
Bearbeitet, um nicht elegante und nicht getestete Teillösung hinzuzufügen:
Außerdem habe ich die No-Loops-Anforderung verletzt.
quelle
Ich belebe diesen Beitrag wieder, weil ich heute einen Weg finden musste, nicht nur Samstag- und Sonntag- Wochentage, sondern auch Feiertage auszuschließen . Insbesondere musste ich verschiedene Arten von möglichen Feiertagen behandeln, einschließlich:
Schließlich kam ich mit den folgenden Hilfs- / Erweiterungsklassen heraus: Obwohl sie nicht besonders elegant sind, da sie ineffiziente Schleifen massiv nutzen, sind sie anständig genug, um meine Probleme endgültig zu lösen. Ich lasse den gesamten Quellcode hier in diesem Beitrag fallen und hoffe, dass er auch für andere nützlich ist.
Quellcode
Nutzungsinformationen
Der Code ist ziemlich selbsterklärend. Hier sind jedoch einige Beispiele, um zu erklären, wie Sie ihn verwenden können.
Fügen Sie 10 Werktage hinzu (überspringen Sie nur die Wochentage Samstag und Sonntag).
Fügen Sie 10 Werktage hinzu (Überspringen von Samstag, Sonntag und allen länderinvarianten Feiertagen für 2019)
Fügen Sie 10 Werktage hinzu (Überspringen von Samstag, Sonntag und allen italienischen Feiertagen für 2019)
Fügen Sie 10 Werktage hinzu (Überspringen von Samstag, Sonntag, allen italienischen Feiertagen und den Rom-spezifischen Feiertagen für 2019)
Die obigen Funktionen und Codebeispiele werden in diesem Beitrag meines Blogs näher erläutert .
quelle
quelle
Ich wollte einen "AddBusinessDays", der eine negative Anzahl von Tagen unterstützt, und am Ende kam ich zu folgendem Ergebnis:
Keine Schleife erforderlich, daher sollte sie auch für "große" Ergänzungen relativ schnell sein.
Es funktioniert mit Tagen, die als Anzahl von Kalendertagen seit der Epoche ausgedrückt werden, da dies von der neuen JDK8 LocalDate-Klasse verfügbar gemacht wird und ich in Java gearbeitet habe. Sollte jedoch einfach an andere Einstellungen anzupassen sein.
Die grundlegenden Eigenschaften sind, dass
addDays
immer ein Wochentag zurückgegeben wird, und das für alled
undn
,daysBetween(d, addDays(d, n)) == n
Beachten Sie, dass das Hinzufügen von 0 Tagen und das Subtrahieren von 0 Tagen theoretisch unterschiedliche Vorgänge sein sollten (wenn Ihr Datum ein Sonntag ist, sollten Sie durch Hinzufügen von 0 Tagen bis Montag und durch Subtrahieren von 0 Tagen bis Freitag geführt werden). Da es keine negative 0 gibt (außerhalb des Gleitkommas!), Habe ich beschlossen, ein Argument n = 0 so zu interpretieren , dass es null Tage addiert .
quelle
Ich glaube, dies könnte ein einfacherer Weg zu GetBusinessDays sein:
quelle
Hier ist mein Code mit dem Abreisedatum und dem Lieferdatum beim Kunden.
Viel Spaß beim Codieren.
quelle
quelle
quelle
Hoffe das hilft jemandem.
quelle