Announcement

Collapse
No announcement yet.

Feiertagsproblematik - Fragen ob ein Tag Feiertag ist oder nicht

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Feiertagsproblematik - Fragen ob ein Tag Feiertag ist oder nicht

    Hi,
    ich hab aus dem Buch
    "Das C# Codebook" den Code für die Ermittlung der Feiertage in einem bestimmten Jahr.

    Das Programm gibt soweit alle Feiertage aus, doch nun steh ich vor folgendem Problem. Ich möchte erreichen, dass der Nutzer den Monat als Zahl und den Tag als Zahl angeben kann. Dabei soll beachtet werden, dass nur die Monate:
    1, 3, 5,7,8,10,12 -> max. 31 Tage
    4,6,9,11 -> max. 30 Tage
    und je nachdem ob es ein Schaltjahr ist oder nicht
    2 -> max. 28 oder max. 29 Tage
    haben.

    mein bisheriger Versuch scheiterete daran, dass day innerhalb einer if und do-while -Anweisung war. Und deshalb konnte es immer nicht ermittelt werden. Hier mal der Codeauszug

    [highlight=c#] //diese Methode dient zur Ermittlung ob ein Tag ein Feiertag ist oder nicht.
    public static bool IsGermanHoliday(DateTime date, out string name, out bool nationWide)
    {
    //out-Argumente initialisieren
    name = null;
    nationWide = false;

    ///summary
    ///Auflistung der besonderen Tage des angegeben Jahres erzeugen,
    ///durchgehen und das Datum der Feiertage mit dem angegebenen Datum vergleichen
    ///summary

    foreach (GermanSpecialDay gsd in GetGermanSpecialDays(date.Year).Values)
    {
    if (date.Day == gsd.Date.Day && date.Month == gsd.Date.Month)
    {
    //Dateum gefunden
    if (gsd.Holiday)
    {
    //Es ist ein Feiertag: Infos definierten und true zurückgeben
    name = gsd.Name;
    nationWide = gsd.Nationwide;
    return true;
    }
    else
    //kein Feiertag
    return false;
    }
    }
    // Tag wurde nicht gefunden
    return false;
    }
    [/highlight]

    hier der Main-Teil

    [highlight=c#]
    int month;
    int day;
    string name;
    bool nationWide;

    do
    {
    Console.WriteLine("Welcher Monat? (Zahl)");
    month = Convert.ToInt32(Console.ReadLine());
    } while (month > 12);

    //if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)

    do
    {

    Console.WriteLine("Welcher Tag? (Zahl)");
    day = Convert.ToInt32(Console.ReadLine());

    }while (day > 31);


    /*if (month == 4 || month == 6 || month == 9 || month == 11 )
    {
    do
    {
    Console.WriteLine("Welcher Tag? (Zahl)");
    day = Convert.ToInt32(Console.ReadLine());
    } while (day > 30);

    }
    if (month == 2)
    {
    if (DateTime.Now.Year % 4 == 0)
    {
    do
    {
    Console.WriteLine("Welcher Tag? (Zahl)");
    day = Convert.ToInt32(Console.ReadLine());
    } while (day > 29);

    }
    else
    {
    do
    {
    Console.WriteLine("Welcher Tag? (Zahl)");
    day = Convert.ToInt32(Console.ReadLine());
    } while (day > 28);

    }

    }*/



    DateTime date = new DateTime(DateTime.Now.Year, month, day);

    if(IsGermanHoliday(date, out name, out nationWide))
    {
    if(nationWide)
    Console.WriteLine("Der {0} ist ein bundesweiter Feiertag: {1}", date.ToShortDateString(), name);
    else
    Console.WriteLine("Der {0} ist ein lokaler Feiertag: {1}", date.ToShortDateString(), name);

    }
    else
    Console.WriteLine("Der {0} ist kein Feiertag", date.ToShortDateString());
    Console.WriteLine();
    Console.ReadLine();
    [/highlight]

    //Edit: so wie der Main-Teil auskommentiert ist funktionierts, aber die Gefahr einen 30. Februar zu bekommen ist sehr groß.
    Gruß
    Flachsi87


    Was ich nutze:
    VS 2008, MS SQL Server 2005

    Kenntnisstand:
    Laie/Interessiert aber sehr unwissend

  • #2
    Und warum fügst du eine Prüfung für den Februar nicht ein??
    Christian

    Comment


    • #3
      Hi,
      weil "day" dann nicht erkannt wird von
      [highlight=c#]
      DateTime date = new DateTime(DateTime.Now.Year, month, day);
      [/highlight]
      Gruß
      Flachsi87


      Was ich nutze:
      VS 2008, MS SQL Server 2005

      Kenntnisstand:
      Laie/Interessiert aber sehr unwissend

      Comment


      • #4
        Mir ist das komplette Programm unklar

        Du solltest die Eingabe von der Validierung trennen. Nicht alles in x-Schleifen

        - Schleifenstart
        - Daten eingeben lassen
        - Daten prüfen
        - ggf. Fehler ausgeben und zur Neueingabe. Hier endet die Schleife mit der Bedingung, ob Fehler vorhanden sind

        Des Weiteren ist deine Schaltjahresfunktion falsch. Da fehlt die Hälfte
        Christian

        Comment


        • #5
          Es dürften doch folgende Prüfungen anfallen:

          Wenn Monat kleiner 1 oder Monat größer 12 -> Fehler

          Wenn Tag kleiner 1 oder Tag größer 31 -> Fehler

          Wenn Tag größer 30 und Monat ist 4,6,9,11 -> Fehler

          Wenn Tag größer 29 und Monat ist 2 -> Fehler

          Wenn Tag größer 28 und Monat ist 2 und es ist kein Schaltjahr -> Fehler

          ------
          Eleganter lässt sich das mit einem regl. Ausdruck prüfen....
          Christian

          Comment


          • #6
            Originally posted by Flachsi87 View Post
            Hi,
            weil "day" dann nicht erkannt wird von
            [highlight=c#]
            DateTime date = new DateTime(DateTime.Now.Year, month, day);
            [/highlight]

            Du bekommst doch eine ArgumentException wenn das ein ungültiges Datum ergibt (wie z.B. der 30.Februar). Also einfach die Exception fangen und dem User eine nette Meldung anzeigen das das Datum ungültig ist.

            Comment


            • #7
              Hi,
              ich bin ja noch in einer Art "Lernphase" ich lasse mich gern belehren und höre mir Lösungsvorschläge an.
              @ Christian Danke, dass du mich auf die Dinge aufmerksam gemacht hast, die ich vergessen habe.
              Frage: Warum ist die Schaltjahresfunktion falsch? Jedes Jahr das durch 4 ohne Rest teilbar ist, ist doch ein Schaltjahr, oder?

              [highlight=c#]
              //Musterprogramm Schaltjahr

              int year12;
              Console.WriteLine("Jahr?");
              year12 = Convert.ToInt32(Console.ReadLine());
              if (year12 % 4 == 0)
              Console.WriteLine("Ist Schaltjahr");
              else
              Console.WriteLine("Ist nicht Schaltjahr");
              Console.WriteLine();
              Console.ReadLine();
              [/highlight]

              @ Ralf Stimmt wäre auch eine mögliche Variante, danke für den Hinweis
              Gruß
              Flachsi87


              Was ich nutze:
              VS 2008, MS SQL Server 2005

              Kenntnisstand:
              Laie/Interessiert aber sehr unwissend

              Comment


              • #8
                Frage: Warum ist die Schaltjahresfunktion falsch? Jedes Jahr das durch 4 ohne Rest teilbar ist, ist doch ein Schaltjahr, oder?
                Nein,

                Ein Schaltjahr ist alle 4 Jahre, jedoch alle 100 Jahre nicht, dann aber alle 400 Jahre doch.
                Christian

                Comment


                • #9
                  Hi,
                  dann müssen die hier einen Fehler bei ihrer Auflistung haben, oder?
                  //Edit ah oki da stehts ja auch, sorry überlesen.

                  //Edit 2: Wie lass ich denn dann das Schaltjahr richtig berechnen?
                  Gruß
                  Flachsi87


                  Was ich nutze:
                  VS 2008, MS SQL Server 2005

                  Kenntnisstand:
                  Laie/Interessiert aber sehr unwissend

                  Comment


                  • #10
                    Hallo,

                    eine vollständige Prüfung aller deutschen Feiertage (feste, bewegliche, regionale) findest du unter Und nochmal eine Feiertagsberechnung (02.12.2007 17:17)

                    Gruß Jürgen

                    Comment


                    • #11
                      Hi,
                      das Programm das ich aus dem Buch, habe ermittelt ja alle Feiertage einwandfrei. Aber ich will jetzt nur noch erreichen, dass ein Tag und ein Monat eingegeben wird und dann geprüft wird ob es sich dabei um einen Feiertag handelt oder nicht.
                      Der Nutzer soll hierbei Tag und Monat eingeben (das soll natürlich auch logisch richtig sein, also so, dass kein Tag angegeben wird, der in dem Monat nicht existiert). Der Code auf myCSharp ist nicht schlecht und beinhaltet im Gegensatz zu meinem auch die Länder, aber eine Prüfmethode mit Tag und Monat eingeben und dann nachgucken lassen ob es ein Feiertag ist oder nicht, entdecke ich gerade nicht.


                      Schaltjahr hab ich jetzt mal manuell umgeändert (sollte für die nächsten 400 Jahre reichen )

                      [highlight=c#]
                      // Schaltjahrberechnung

                      int year12;
                      Console.WriteLine("Jahr?");
                      year12 = Convert.ToInt32(Console.ReadLine());
                      if (year12 % 4 == 0 &&
                      !(year12 == 1900) &&
                      !(year12 == 2100)&&
                      !(year12 == 2200)&&
                      !(year12 == 2300)&&
                      !(year12 == 2500))
                      Console.WriteLine("Ist Schaltjahr");
                      else
                      Console.WriteLine("Ist nicht Schaltjahr");
                      Console.WriteLine();
                      Console.ReadLine();
                      [/highlight]
                      Gruß
                      Flachsi87


                      Was ich nutze:
                      VS 2008, MS SQL Server 2005

                      Kenntnisstand:
                      Laie/Interessiert aber sehr unwissend

                      Comment


                      • #12
                        Hallo,

                        deine Schaltjahrsprüfung geht einfacher mit verschachtelter modulo-Prüfung:
                        Code:
                        bool isLeapYear = (year % 4 == 0 || (year % 100 == 0 && year % 400 != 0));
                        Ich glaube, ich habe noch nicht alle Zusatzbedingungen richtig verknüpft, aber so etwa geht es.

                        Zu meinem Code-Vorschlag: Du brauchst doch aus deiner Eingabe nur ein Datum zu erzeugen und kannst dann eine meiner Methoden aufrufen - etwa so, wie du es auch schon gemacht hast:
                        Code:
                        DateTime date = new DateTime(DateTime.Now.Year, month, day);
                        string einFeiertag = Feiertagsprüfung.Instance.GetName(date);
                        Jürgen

                        PS. Ralf hat natürlich recht: was es schon gibt, kann/darf/soll natürlich benutzt werden. Aber zu Übungszwecken kann man es auch selbst schreiben.
                        Zuletzt editiert von Jürgen Thomas; 07.08.2009, 17:32. Reason: "isLoopYear" war blöde Bezeichnung

                        Comment


                        • #13
                          //Edit 2: Wie lass ich denn dann das Schaltjahr richtig berechnen?
                          Einfach das Framework fragen.

                          Code:
                          int year12;
                          Console.WriteLine("Jahr?");
                          year12 = Convert.ToInt32(Console.ReadLine());
                          
                          if (DateTime.IsLeapYear(year12))
                              Console.WriteLine("Ist Schaltjahr");
                          else
                              Console.WriteLine("Ist nicht Schaltjahr");

                          Comment


                          • #14
                            Hi!

                            Vielen dank noch mal für die Hinweise und Codevorschläge. Sie haben mir wirklich weitergeholfen. Danke!

                            Edit:
                            hab das Problem mit den max. möglichen Tagen jetzt so gelöst:

                            [highlight=c#]

                            public static bool IstTag (int day, int month, int year)
                            {
                            if (day <= 0)
                            return false;
                            if (day >= 1 || day<=30 && (month == 4 || month == 6 || month == 9 || month == 11))
                            return true;
                            if(day>=1||day<=31 && (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12))
                            return true;
                            if (day >= 1 || day <= 29 && month == 2 && DateTime.IsLeapYear(year))
                            return true;
                            if (day >= 1 || day <= 28 && month == 2 && !DateTime.IsLeapYear(year))
                            return true;
                            return false;
                            }

                            [/highlight]

                            Die Funktion rufe ich im main-Teil auf wodurch die falschen Eingaben verhindert werden. Aber wie kann ich es nun umgehen, dass der Nutzer bei einer falschen Eingabe in den Quellcode geführt wird? (ich glaub da hab ich irgendwo einen Fehler eingebastelt...). Bin diesbezüglich für jeden Rat dankbar. Da das Programm aus Testzwecken erst Mal als Konsolenanwendung vorhanden ist kann ich auch kein show anwenden.

                            Main-Teil-Auszug:

                            [highlight=c#]

                            if (IstTag(day, month, year))
                            {
                            if (IsGermanHoliday(date, out name, out nationWide))
                            {
                            if (nationWide)
                            Console.WriteLine("Der {0} ist ein bundesweiter Feiertag: {1}", date.ToShortDateString(), name);
                            else
                            Console.WriteLine("Der {0} ist ein lokaler Feiertag: {1}", date.ToShortDateString(), name);

                            }
                            else
                            Console.WriteLine("Der {0} ist kein Feiertag", date.ToShortDateString());
                            Console.WriteLine();
                            Console.ReadLine();
                            }
                            else
                            Console.WriteLine("Ungültiger Ausdruck");

                            [/highlight]

                            Wie kann ich diese Art der Fehlermeldung umgehen und dem Nutzer vorerst in der Konsolenanwendung anzeigen lassen, dass die Eingabe ungültig ist?
                            Zuletzt editiert von Flachsi87; 10.08.2009, 08:50.
                            Gruß
                            Flachsi87


                            Was ich nutze:
                            VS 2008, MS SQL Server 2005

                            Kenntnisstand:
                            Laie/Interessiert aber sehr unwissend

                            Comment


                            • #15
                              Aber wie kann ich es nun umgehen, dass der Nutzer bei einer falschen Eingabe in den Quellcode geführt wird? (ich glaub da hab ich irgendwo einen Fehler eingebastelt...).
                              Du meinst du landest bei einem Fehler in Visual Studio? Das ist normal und nennt man Debugging Ein späterer Nutzer würde das Programm wohl kaum aus Visual Studio heraus mit Debugger starten.

                              Comment

                              Working...
                              X