myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns
» Datenschutzerklärung
» Impressum

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » Und nochmal eine Feiertagsberechnung
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Und nochmal eine Feiertagsberechnung

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Lars Schmitt Lars Schmitt ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2240.jpg


Dabei seit: 11.10.2005
Beiträge: 2.216
Entwicklungsumgebung: Visual Studio 2013
Herkunft: Witten


Lars Schmitt ist offline

Und nochmal eine Feiertagsberechnung

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschreibung:

Jedoch kann bei dieser Feiertagsberechnung das jeweilige Land mit berücksichtigt werden

C#-Code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;



namespace BlackDragon.FeierTage {

    /// <summary>

    /// Und nochmal eine Feiertagsberechnung

    /// </summary>

    public class FeierTage {
        private List<FeierTag> feiertage = new List<FeierTag>();

        public FeierTage() {
            Initial();
        }


        /// <summary>

        /// Den möglichen Feiertags anhand des Datums und des jeweiligen Bundes Landes ermitteln

        /// </summary>

        /// <param name="datum">Das Datum, daß zur ermittlung herrangezogen werden soll</param>

        /// <param name="land">Das jeweilige Land</param>

        /// <returns>Der jeweilige Feiertag als Text</returns>

        public String GetFeiertag(DateTime datum, Land land) {

            // Liste der Feiertage durchgehen

            foreach (FeierTag f in feiertage) {
                if (datum.ToShortDateString().Equals(f.GetDatum(GetOstersonntag(datum.Year)).ToShortDateString())) {
                    // Prüfen ob das Land enthalten ist

                    foreach (Land l in f.Länder) {
                        if (land == l) {
                            return f.Feiertag;
                        }
                    }
                }
            }
            return "";
        }

        /// <summary>

        /// Einfache Abfrage ob das übergeben Datum in dem jeweiligen Land ein Feiertag ist

        /// </summary>

        /// <param name="datum">Das Datum, daß zur ermittlung herrangezogen werden soll</param>

        /// <param name="land">Das jeweilige Land</param>

        /// <returns>Wahr oder Falsch</returns>

        public Boolean IsFeiertag(DateTime date, Land land) {
            return (GetFeiertag(date, land).Length > 0);
        }

        /// <summary>

        /// Errechnet das Datum des Ostersonntags aus dem übergebenen Jahr

        /// </summary>

        /// <param name="int">Das Jahr in YYYY Schreibweise</param>

        /// <returns>Das errechnete Datum des Ostersonnsags in dem angegebene Jahr</returns>

        private DateTime GetOstersonntag(int jahr) {
            int c;
            int i;
            int j;
            int k;
            int l;
            int n;
            int OsterTag;
            int OsterMonat;
          
            c = jahr / 100;
            n = jahr - 19 * ((int)(jahr / 19));
            k = (c - 17) / 25;
            i = c - c / 4 - ((int)(c - k) / 3) + 19 * n + 15;
            i = i - 30 * ((int)(i / 30));
            i = i - (i / 28) * ((int)(1 - (i / 28)) * ((int)(29 / (i + 1))) * ((int)(21 - n) / 11));
            j = jahr + ((int)jahr / 4) + i + 2 - c + ((int)c / 4);
            j = j - 7 * ((int)(j / 7));
            l = i - j;

            OsterMonat = 3 + ((int)(l + 40) / 44);
            OsterTag = l + 28 - 31 * ((int)OsterMonat / 4);

            return Convert.ToDateTime(OsterTag.ToString() + "." + OsterMonat + "." + jahr);
        }


        /// <summary>

        /// Die einzelnen möglichen Feiertage

        /// kan natürlich noch erweitert werden

        /// </summary>

        private void Initial() {
            Land[] alle = new Land[] { Land.Baden_Würtenberg, Land.Bayern, Land.Berlin, Land.Brandenburg, Land.Bremen, Land.Hamburg, Land.Hessen, Land.Mecklenburg_Vorpommern, Land.Niedersachsen, Land.Nordrhein_Westfalen, Land.Rheinland_Pfalz, Land.Saarland, Land.Sachsen, Land.Sachsen_Anhalt, Land.Schleswig_Holstein, Land.Thüringen };

            feiertage.Add(new FeierTag("Neujahr","01.01", FeiertagsArt.Fester_Feiertag, alle));
            feiertage.Add(new FeierTag("Heiligen Drei Könige", "06.01", FeiertagsArt.Fester_Feiertag, new Land[] { Land.Baden_Würtenberg, Land.Bayern, Land.Sachsen_Anhalt }));
            feiertage.Add(new FeierTag("Karfreitag", -2, FeiertagsArt.Bewegliche_Feiertag, alle));
            feiertage.Add(new FeierTag("Ostersonntag", 0, FeiertagsArt.Bewegliche_Feiertag, alle));
            feiertage.Add(new FeierTag("Ostermontag", 1, FeiertagsArt.Bewegliche_Feiertag, alle));
            feiertage.Add(new FeierTag("Tag der Arbeit", "01.05", FeiertagsArt.Fester_Feiertag, alle));
            feiertage.Add(new FeierTag("Christi Himmelfahrt", 39, FeiertagsArt.Bewegliche_Feiertag , alle));
            feiertage.Add(new FeierTag("Pfingstsonntag", 49, FeiertagsArt.Bewegliche_Feiertag, alle));
            feiertage.Add(new FeierTag("Pfingstmontag", 50, FeiertagsArt.Bewegliche_Feiertag, alle));
            feiertage.Add(new FeierTag("Fronleichnam", 60, FeiertagsArt.Bewegliche_Feiertag, new Land[] { Land.Baden_Würtenberg, Land.Bayern, Land.Hessen, Land.Nordrhein_Westfalen, Land.Rheinland_Pfalz,Land.Saarland}));
            feiertage.Add(new FeierTag("Mariä Himmelfahrt", "15.08", FeiertagsArt.Fester_Feiertag, new Land[] { Land.Saarland }));
            feiertage.Add(new FeierTag("Tag der dt. Einheit", "03.10", FeiertagsArt.Fester_Feiertag, alle ));
            feiertage.Add(new FeierTag("Allerheiligen", "01.11", FeiertagsArt.Fester_Feiertag, new Land[] { Land.Baden_Würtenberg,Land.Bayern,Land.Nordrhein_Westfalen,Land.Rheinland_Pfalz,Land.Saarland }));
            feiertage.Add(new FeierTag("1. Weinachtstag", "25.12", FeiertagsArt.Fester_Feiertag, alle));
            feiertage.Add(new FeierTag("2. Weinachtstag", "26.12", FeiertagsArt.Fester_Feiertag, alle));

        }
    }

    /// <summary>

    /// Die eigentliche Klasse der einzelnen Feiertage

    /// </summary>

    internal class FeierTag {
        private FeiertagsArt art;
        private string feiertag;
        private DateTime datum;
        private string testDatum;
        private int tageHinzu;
        private Land[] länder;

        public String Feiertag {
            get {
                return this.feiertag;
            }
        }
        public DateTime Datum {
            get {
                return this.datum;
            }
        }
        public Land[] Länder {
            get {
                return länder;
            }
        }

        internal FeierTag(String feiertag, String testDatum, FeiertagsArt art, Land[] länder) {
            this.feiertag = feiertag;
            this.testDatum = testDatum;
            this.tageHinzu = 0;
            this.art = art;
            this.länder = länder;
        }
        internal FeierTag(String feiertag, int tageHinzu, FeiertagsArt art, Land[] länder) {
            this.feiertag = feiertag;
            this.tageHinzu = tageHinzu;
            this.art = art;
            this.länder = länder;
        }
        
        public DateTime GetDatum(DateTime osterSonntag) {
            if (this.art != FeiertagsArt.Fester_Feiertag) {
                datum = osterSonntag.AddDays(this.tageHinzu);
            } else {
                datum = DateTime.Parse(testDatum + "." + osterSonntag.Year);
            }

            return DateTime.Parse(datum.Day.ToString() + "." + datum.Month.ToString() +"."+ osterSonntag.Year);
        }
    }

    public enum Land {
        Baden_Würtenberg,
        Bayern,
        Berlin,
        Brandenburg,
        Bremen,
        Hamburg,
        Hessen,
        Mecklenburg_Vorpommern,
        Niedersachsen,
        Nordrhein_Westfalen,
        Rheinland_Pfalz,
        Saarland,
        Sachsen,
        Sachsen_Anhalt,
        Schleswig_Holstein,
        Thüringen
    }
    public enum FeiertagsArt {
        Fester_Feiertag,
        Bewegliche_Feiertag
    }
}

Schlagwörter: Feiertage, Osterformel

Quelle: .NET-Snippets
30.04.2007 10:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 6 Monate.
juetho juetho ist männlich
myCSharp.de-Mitglied

Dabei seit: 23.10.2006
Beiträge: 3.331
Entwicklungsumgebung: #D NET 2.0 / Firebird (Win10)
Herkunft: Berlin


juetho ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

das ist eine schöne Zusammenstellung. Ich möchte sie gerne erweitern:
* bundesweite Feiertage vereinfacht bestimmen
* als Singleton-Klasse
* mit statischen Abfragen
Wenn ich sowieso schon dabei bin, würde ich die Bundesländer nach den Nummern des Statistischen Bundesamtes indizieren.

Gibt es Interesse daran, diese Änderungen hier bereitzustellen? Jürgen
29.11.2007 17:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.453
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo juetho,

für mich klingt das nach zwar nicht nach Erweiterungen, sondern "nur" nach Änderungen, aber es spricht auch nichts dagegen, deinen "Konkurrenzentwurf" hier zu veröffentlichen.

herbivore
29.11.2007 17:31 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
blackman1983
myCSharp.de-Mitglied

Dabei seit: 20.06.2007
Beiträge: 114
Entwicklungsumgebung: Visual Studio 2008


blackman1983 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

also is ja an sich nur Rechnerei, weil ja wohl durch Kirche u. Co alles irgendwie von Ostern ausgeht. Aber sehr interessant find ich ja wie du überhaupt auf das Datum vom Ostersonntag kommst. Is doch eigentlich vom Mond abhängig oder gibts da ne allgemeine Regel für?
Bräuchte das auch für nen Projekt.
Hast da vlt ma nen Algorithmus im Wortlaut bzw nich so böse hingecodet?
Konnte bisher rausfinden wieviele Tage von Ostern die anderen Feiertage entfernt sind, aber halt nich Ostern an sich.

Gruß
Black
30.11.2007 22:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
langalaxy langalaxy ist männlich
myCSharp.de-Mitglied

avatar-1914.gif


Dabei seit: 30.11.2005
Beiträge: 664
Entwicklungsumgebung: VS 2008


langalaxy ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Original von blackman1983
Is doch eigentlich vom Mond abhängig oder gibts da ne allgemeine Regel für?

Osterformel von C. F. Gauss ->  http://www.nabkal.de/gauss2.html
30.11.2007 22:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
juetho juetho ist männlich
myCSharp.de-Mitglied

Dabei seit: 23.10.2006
Beiträge: 3.331
Entwicklungsumgebung: #D NET 2.0 / Firebird (Win10)
Herkunft: Berlin


juetho ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Überlegungen für Änderungen

Wie ich schon schrieb, wollte ich Blackcoin's Lösung ergänzen. Die folgenden Überlegungen haben mich dabei zu entsprechenden Änderungen geführt.

Art der Feiertage
Das habe ich zu einer bool-Variable "beweglich" vereinfacht. Andere Varianten gibt es schließlich nicht. Außerdem habe ich zur Vereinfachung der Prüfungen die bool-Variable "bundesweit" hinzufügt.

Für die Bezeichnung eines Feiertags (bei Blackcoin als "feiertag" bzw. "GetFeiertag" bezeichnet) benutze ich "name" bzw. "Name" oder "GetName".

Singleton-Klasse
Für die Feiertagsberechnung gibt es "inhaltlich" innerhalb einer Anwendung (eigentlich: in einem lokalen Netzwerk) zwangsläufig nur eine Variante. Es bietet sich deshalb an, den Aufruf über eine Singleton-Klasse zu steuern. Beim erstmaligen Aufruf wird die interne Klasse erstellt. Alle Methoden für Prüfungen stehen als "Schnittstelle" in der Singleton-Klasse.

C#-Code:
public sealed class Feiertagsprüfung
{
    private static Feiertagsprüfung
        instance = new Feiertagsprüfung();
    private Feiertage interna;

    public static Feiertagsprüfung Instance {
        get {
            if (instance == null)
                instance = new Feiertagsprüfung();
            return instance;
        }
    }

    private Feiertagsprüfung()
    {
        interna = new Feiertage();
    }
}

Prüfmethoden
Ausgehend von Blackcoin's Konzept habe ich die folgenden Verfahren übernommen und für bundesweite Feiertage ergänzt sowie in die Singleton-Klasse eingebaut.

C#-Code:
/// Einfache Abfrage, ob das übergebene Datum überhaupt ein Feiertag ist
public static bool IsFeiertag(DateTime datum, bool bundesweit) { }
/// Einfache Abfrage, ob das Datum in dem jeweiligen Land ein Feiertag ist
public static bool IsFeiertag(DateTime datum, Land land) { }
/// Ergänzende Prüfung, ob das übergebene Datum
/// in (irgend-)einem Land teilweise ein Feiertag ist
public static bool IsTeilweiseFeiertag(DateTime datum) {  }
/// Die Bezeichnung eines bundesweiten Feiertags anhand des Datums ermitteln
public static string GetName(DateTime datum) { }
/// Die Bezeichnung eines möglichen Feiertags anhand des Datums
/// und des jeweiligen Bundeslandes ermitteln
public static string GetName(DateTime datum, Land land) {
    return Instance.interna.GetName(datum, land);
}

Diese Methoden leiten (wie im letzten Beispiel) die Parameter an die entsprechenden Methoden in der internen Klasse weiter. Beispielhaft wird die letzte Prüfung so ausgeführt:

C#-Code:
public string GetName(DateTime datum, Land land) {
    string Result = String.Empty;
    Feiertag f = GetFeiertag(datum);
    if (f != null) {
        if (f.Bundesweit || Array.IndexOf(f.Länder, land) >= 0)
            Result = f.Name;
    }
    return Result;
}

Interne Liste als List<T> oder Dictionary<string, T>
Blackcoin's Verfahren, bei dem "Datümer" per String verglichen werden und die Strings in jedem Schritt der foreach-Schleife neu erstellt werden, gefiel mir nicht besonders. Das Verfahren kann hingenommen werden, weil es sich nur um wenige Einträge handelt und die beweglichen Feiertage für jedes Jahr getrennt berechnet werden müssen.

Aber genau wegen der Berechnung pro Jahr scheint mir die getrennte Speicherung sinnvoll zu sein. Dann können die Listen auch konsequent als Nachschlagetabellen genutzt werden, auch wenn ihre Erstellung ein klein wenig umständlicher aussieht.

C#-Code:
//  feste Feiertage mit Suche nach "01.01."
private Dictionary<string, Feiertag> festeFeiertage
    = new Dictionary<string, Feiertag> ();
festeFeiertage.Add("01.01.", new Feiertag("Neujahr", "01.01."));

//  bewegliche Feiertage mit Suche nach Jahr und Datum
private Dictionary<int, Dictionary<DateTime, Feiertag>> beweglicheFeiertage
    = new Dictionary<int, Dictionary<DateTime, Feiertag>> ();
DateTime ostern = GetOstersonntag(jahr);
//  daraus alle "abhängigen" Feiertage ableiten und registrieren
aktuelleFeiertage.Add(ostern.AddDays(-2),
    new Feiertag("Karfreitag", ostern, -2));

Die eigentliche Prüfung wird durch den Dictionary-Aufbau erheblich vereinfacht und jeweils in der folgenden Methode erledigt:

C#-Code:
private Feiertag GetFeiertag(DateTime datum)
{
    Feiertag Result = null;
    //  erster Versuch: fester Feiertag?
    string ttmm = datum.ToString("dd.MM.");
    if (! festeFeiertage.TryGetValue(ttmm, out Result)) {
        //  zweiter Versuch:
        //  bewegliche Feiertage des betreffenden Jahres feststellen
        Dictionary<DateTime, Feiertag> beweglich = null;
        int jahr = datum.Year;
        if (! beweglicheFeiertage.TryGetValue(jahr, out beweglich)) {
            //  noch nicht vorhanden,
            //  also hinzufügen und verwenden
            InitBeweglicheFeiertage(jahr);
            beweglich = beweglicheFeiertage[jahr];
        }
        beweglich.TryGetValue(datum, out Result);
    }
    return Result;
}

Besondere Feiertage
Fronleichnam und Mariä Himmelfahrt sind in manchen Bundesländern nur teilweise Feiertag. Dafür habe ich in der Enumeration der Bundesländer an Position Null die Angabe "teilweise" hinzugefügt. Ein solcher Feiertag muss also bei Bedarf genauer geprüft werden.
Diese Länder können in den Methoden InitFesteFeiertage() und InitBeweglicheFeiertage() anstatt "teilweise" eingetragen werden.

Der Buß- und Bettag ist nur noch in Sachsen Feiertag und errechnet sich auf besondere Weise; dafür gibt es also analog zu GetOstersonntag() eine eigene Berechnungsmethode.

Wenn der 1. Mai gleichzeitig Tag der Arbeit und Christi Himmelfahrt ist, wird nur der feste Feiertag angezeigt, weil dies in der o.g. Prüfung Vorrang hat.

Außerdem entspricht die Reihenfolge der Liste der Bundesländer jetzt dem  Gemeindeverzeichnis des Stat. Bundesamtes.

Die vollständige, aktuelle Version habe ich als Anlage beigefügt. (Die Anlage enthält außerdem eine Anwendung, die alle Methoden für alle Bundesländer in den Jahren 2006, 2007, 2008 demonstriert.)

Jürgen Thomas (juetho)

Urheber
Sowohl der Hauptgedanke mit den beiden Klassen "Einzelner Feiertag" und "Alle Feiertage" sowie den Prüfungsvorgängen und den Klassenelementen als auch die unabdingbar notwendige, wichtige und saubere Berechnung des Ostersonntags stammen von  blackcoin. Die Ergänzungen mit Dictionary und Singleton-Klasse sowie dadurch einfacheren Prüfmethoden stammen von  juetho.

Unabhängig davon gelten natürlich die  Nutzungsbedingungen von myCSharp.de.

Nachtrag: (2016) Die Anlage Feiertage.zip wurde ersetzt durch die korrigierte Version im folgenden Beitrag.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von juetho am 14.07.2016 16:30.

02.12.2007 17:17 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 8 Jahre.
juetho juetho ist männlich
myCSharp.de-Mitglied

Dabei seit: 23.10.2006
Beiträge: 3.331
Entwicklungsumgebung: #D NET 2.0 / Firebird (Win10)
Herkunft: Berlin


juetho ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wichtiger Hinweis: Die vorstehende Berechnung genügt nicht: Zwei Ausnahmeregeln wurden bei den obigen Lösungen nicht in die Gaußsche Formel eingearbeitet. Der Ordnung halber folgt hier die berichtigte Berechnung:

C#-Code:
    /// <summary>
    /// Errechnet das Datum des Ostersonntags aus dem übergebenen Jahr
    /// </summary>
    /// <param name="jahr">Das Jahr YYYY als integer-Wert</param>
    /// <returns>Das errechnete Datum des Ostersonntags in dem angegebenen Jahr</returns>
    private DateTime GetOstersonntag(int jahr)
    {
      int x = jahr;   // das Jahr
      int k;          // die Säkularzahl
      int m;          // die säkulare Mondschaltung
      int s;          // die säkulare Sonnenschaltung
      int a;          // der Mondparameter
      int d;          // der Keim für den ersten Vollmond im Frühling
      int r;          // die kalendarische Korrekturgröße
      int og;         // die Ostergrenze
      int sz;         // der ersten Sonntag im März
      int oe;         // die Entfernung des Ostersonntags von der Ostergrenze
      int os;         // das Datum des Ostersonntags als Märzdatum (32.März = 1.April)
      int OsterTag;
      int OsterMonat;

      k = x / 100;
      m = 15 + (3 * k + 3) / 4 - (8 * k + 13) / 25;
      s = 2 - (3 * k + 3) / 4;
      a = x % 19;
      d = (19 * a + m) % 30;
      r = (d + a / 11) / 29;
      og = 21 + d - r;
      sz = 7 - (x + x / 4 + s) % 7;
      oe = 7 - (og - sz) % 7;
      os = og + oe;

      OsterMonat = 2 + (int)(os + 30) / 31;
      OsterTag = os - 31 * ((int)OsterMonat / 4);

      return Convert.ToDateTime(OsterTag.ToString() + "." + OsterMonat + "." + jahr);
    }

[offtopic]Auf diesen Fehler wurde ich kürzlich durch eine Änderung bei der  Wikibooks-Algorithmensammlung aufmerksam gemacht.[/offtopic]

Die hier stehende Version von Feiertage.zip habe ich entsprechend ergänzt.

Quelle:  Gaußsche Osterformel (mit Ergänzung)
Hinweis: Der letzte Beitrag bei  Osterformel nach Carl Friedrich Gauß enthält die vollständige Lösung.

Nachtrag: Die Anlage Feiertage.zip wurde ersetzt durch die korrigierte Version in meinem nächsten Beitrag (27.09.2016).

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von juetho am 27.09.2016 12:56.

14.07.2016 16:28 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
sheitman sheitman ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.11.2005
Beiträge: 1.047


sheitman ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

wollte noch anmerken das die Buß und Bettag Berechnung auch fehlerhaft ist.
Ist mir für 2000, 2006, 2017 und 2023 aufgefallen. Es ist jedes mal der 15. statt der 22.

Laut  Buß- und Bettag ist der Feiertag so definiert das es der Mittwoch vor dem 23. November ist. D.h. der Code kann auch sehr stark vereinfacht werden.

Mit folgender Hilfsmethode

C#-Code:
public static DateTime GetLastWeekday(this DateTime startDate, DayOfWeek targetDayOfWeek) {
    DayOfWeek startDayOfWeek =  startDate.DayOfWeek;
    if (startDayOfWeek == targetDayOfWeek) {
        return startDate;
    }
    int diff = 0;
    if (startDayOfWeek < targetDayOfWeek) {
        diff = targetDayOfWeek - startDayOfWeek - 7;
    } else if (startDayOfWeek > targetDayOfWeek) {
        diff = targetDayOfWeek - startDayOfWeek;
    }
    return startDate.AddDays(diff);
}

Lässt sich der Buß und Bettag dann so berechnen

C#-Code:
DateTime GetBussUndBettag(int year) {
    return new DateTime(year, 11, 22).GetLastWeekday(DayOfWeek.Wednesday);
}

@juetho
bei GetOstersonntag, die letzte Zeile, da würde ich anstelle

C#-Code:
return Convert.ToDateTime(OsterTag.ToString() + "." + OsterMonat + "." + jahr);

einfach den Konstruktor von DateTime verwenden

C#-Code:
return new DateTime(jahr, OsterMonat, OsterTag);

Gruß
Sven

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von sheitman am 01.09.2016 12:21.

01.09.2016 12:21 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
juetho juetho ist männlich
myCSharp.de-Mitglied

Dabei seit: 23.10.2006
Beiträge: 3.331
Entwicklungsumgebung: #D NET 2.0 / Firebird (Win10)
Herkunft: Berlin


juetho ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke für die Hinweise. Ich habe deine (sheitman) Vorschläge eingearbeitet.

Bei der Gelegenheit habe ich die Anzeige der Anwendung etwas erweitert, sodass man Ostersonntag und Buß- und Bettag für ein "beliebiges" Jahr direkt prüfen kann. Damit kommen solche Fehler hoffentlich nicht mehr vor.

[offtopic]Ich wundere mich, dass ich den Buß- und Bettag nicht kontrolliert hatte. Ebenso wundere ich mich über die Convert-Anweisung beim Ostersonntag; solche Konstruktionen hatte ich eigentlich schon vor neun Jahren als schlechten Stil abgelehnt. Besser spät als nie korrigieren![/offtopic]

Die Version von Feiertage.zip habe ich entsprechend ergänzt.


Dateianhang:
unknown Feiertage.zip (16 KB, 379 mal heruntergeladen)
27.09.2016 12:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
p!lle
myCSharp.de-Mitglied

avatar-3556.jpg


Dabei seit: 22.02.2007
Beiträge: 979
Entwicklungsumgebung: Visual Studio (Community) 2017


p!lle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Grade mitbekommen, dass der Reformationstag 2017 in ganz Deutschland gefeiert werden soll, siehe auch  Wikipedia.
28.10.2016 14:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegen mehr als 2 Monate.
live2 live2 ist männlich
myCSharp.de-Mitglied

Dabei seit: 14.11.2005
Beiträge: 33


live2 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zu diesem Thema gibt es auch ein C# Projekt auf Github. Die Feiertage werden auch Dynamisch berechnet und es werden derzeit 23 Länder unterstützt. Deutschland ist eines davon, die Bundesländer werden auch berücksichtigt

 https://github.com/tinohager/Nager.Date

C#-Code:
var publicHolidays = DateSystem.GetPublicHoliday("DE", 2017);
foreach (var publicHoliday in publicHolidays)
{
    Console.WriteLine(publicHoliday.Name);
}

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von live2 am 05.01.2017 14:47.

05.01.2017 14:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 12 Jahre.
Der letzte Beitrag ist älter als 2 Jahre.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 26.05.2019 13:01