Autor Beitrag
ThomAlex
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58

Windows 7
C# (VS08) Games via XNA (privat) oder WinForms (Schule)
BeitragVerfasst: Do 22.04.10 20:36 
Hallo,

ich habe ein kleines Programm geschrieben, dass die Eingabe von Jahr, Monat und Tag mit einem Algorithmus verarbeitet, der mir ausspuckt, welcher Tag im Jahr das ist. Miteinbezogen sind Schaltjahre, diese haben 366 Tage und um die grogorianische Schaltregel mal einfachheitshalber außen vor zu lassen, ist jedes vierte Jahr ein Schaltjahr (also das Jahr geteilt durch 4 darf keinen Rest aufweisen). Es klappt, nur ich möchte versuchen den Code von der Menge soweit zu kürzen, wie es nur geht, habt ihr Ideen, wie ich den verkürzen kann? Hier der Code:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
int result, userday, usermonth, useryear;
int[] monthdays = new int[12];

private void button1_Click(object sender, EventArgs e)
{
       userday = 0;
       usermonth = 0;
       useryear = 0;

       //Day
       if (int.Parse(txtDays.Text) > 0 && int.Parse(txtDays.Text) <= 31)
            userday = int.Parse(txtDays.Text);
       else
       {
            MessageBox.Show("Ungültige Eingabe für den Tag!");
            txtDays.Text = "";
            return;
       }

       //Month
            
       if (int.Parse(txtMonth.Text) <= 12 && int.Parse(txtMonth.Text) >= 1)
            usermonth = int.Parse(txtMonth.Text);
       else
       {
            MessageBox.Show("Ungültige Eingabe für den Monat!");
            txtMonth.Text = "";
            return;
       }
       //Year
            
       try { useryear = int.Parse(txtYear.Text); }
       catch
       {
            MessageBox.Show("Ungültige Eingabe!");
            txtYear.Text = "";
            return;
       }

       result = 0;

       for (int i = 0; i < 12; i++)
       {
            if (i == 0 || i == 2 || i == 4 || i == 6 || i == 7 || i == 9 || i == 11)
                monthdays[i] = 31;
            else if (i == 1 && useryear % 4 == 0)
                monthdays[i] = 29;
            else if (i == 1 && useryear % 4 != 0)
                monthdays[i] = 28;
            else
                monthdays[i] = 30;
        }
        for (int i = 0; i < usermonth - 1; i++)
            result += monthdays[i];
        result += userday;

        lblAusgabe.Text = result + ". Tag im Jahr " + useryear;
        lblAusgabe.Visible = true;
}

Danke fürs Gedanken machen


Moderiert von user profile iconKha: Topic aus WinForms verschoben am Do 22.04.2010 um 21:20
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 22.04.10 20:55 
Laß das ganze doch das Framework selber rechnen. Ist kompakter und das Schaltjahr Handling ist auch geschenkt.

ausblenden C#-Quelltext
1:
result = new DateTime(useryear, usermonth, userday).Subtract(new DateTime(useryear - 11231)).Days;					
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 22.04.10 21:03 
Ich empfehle DayOfYear. Jürgen
ThomAlex Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58

Windows 7
C# (VS08) Games via XNA (privat) oder WinForms (Schule)
BeitragVerfasst: Do 22.04.10 21:17 
Ja danke für die Methoden, allerdings gehts mir um eine Optimierung meines Codes. Sinn der Sache ist nicht fertigen Code zu benutzen, sondern ihn selber in Kurzform zu programmieren. Kann jemand meinen Code kürzen? Danke
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 22.04.10 21:30 
user profile iconThomAlex hat folgendes geschrieben Zum zitierten Posting springen:
Es klappt, nur ich möchte versuchen den Code von der Menge soweit zu kürzen, wie es nur geht, habt ihr Ideen, wie ich den verkürzen kann?
Der Code ist von der Logik schon ziemlich direkt, da lässt sich wenig rütteln. Aber zwei Anmerkungen: Warum sind die Variablen außerhalb der Methode deklariert? Die meisten 0 Initialisierungen kannst du dir auch sparen. Und wozu erst monthdays füllen und dann direkt zusammenrechnen? Die zwei Schritte könntest du gleichzeitig ausführen und dir so das Array sparen. Oder du ersetzt die Schleife durch Folgendes, imo ein wenig hübscher:
ausblenden C#-Quelltext
1:
int[] monthDays = { 31, userYear % 4 == 0 ? 29 : 283130, ... };					

Und wenn du LINQ magst, kannst du dann mit
ausblenden C#-Quelltext
1:
int result = monthDays.Take(userMonth - 1).Sum() + userDay;					

weitermachen.

/edit: Und noch eine Idee: Das Einlesen der drei Datumsteile in eine Methode bool Validate(TextBox box, string name, int min, int max, out int value) auslagern.

_________________
>λ=


Zuletzt bearbeitet von Kha am Do 22.04.10 21:36, insgesamt 2-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 22.04.10 21:32 
Zitat:
Sinn der Sache ist nicht fertigen Code zu benutzen, sondern ihn selber in Kurzform zu programmieren. Kann jemand meinen Code kürzen


Der Ausspruch ist jetzt aber reichlich Paradox :gruebel:
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Do 22.04.10 21:35 
Okay, dann mache ich mich mal an den Code :)

Zu aller erst könntest du ein NumericUpDown verwenden für die Datum eingabe. Dann brauchst du das Parsen nicht.
Oder eine MaskedTextBoxed, dann kannst du ungültige Eingaben abfangen.

Wenn es aber eine Textbox sein "muss" dann denke ich, dass dir TryParse weiter hilft:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
private void button1_Click(object sender, EventArgs e)
{
   int userday, usermonth, useryear;

   if (!int.TryParse(textDays.Text, out userday) || userday > 31 || userday < 0)
   {
       throw new Exception("Ungültige Tag eingabe");
   }
   if (!int.TryParse(textMonth.Text, out usermonth) || usermonth > 12 || usermonth < 1)
   {
       throw new Exception("Ungültige Monat eingabe");
   }
   if (!int.TryParse(textYear.Text, out useryear))
   {
       throw new Exception("Ungültige Jahr eingabe");
   }

   int[] monthdays = new int[12];
   int sumOfDays;
   for (int i = 0; i < 12; i++)
   {
      switch(i)
      {
         case 0:
         case 2:
         case 4:
         case 6:
         case 7:
         case 9:      
         case 11:
            monthdays[i]= 31;
            break;
         case 1:
            monthdays[i]= useryear % 4 ? 28 : 29;
            break;
         default:
            monthdays[i]= 30;
      }
      sumOfDays += monthdays[i];
   }
   
   lblAusgabe.Text = string.Format("Das Jahr {0} hat {1} Tage.", useryear, sumOfDays);
}


Ich denke das ist selbsterklärend :)

Wenn du fragen hast .. schieß los

Gruß
ThomAlex Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58

Windows 7
C# (VS08) Games via XNA (privat) oder WinForms (Schule)
BeitragVerfasst: Fr 23.04.10 00:07 
Vielen Dank, aus allem hab ich etwas genommen.

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
private void button1_Click(object sender, EventArgs e)
{
       //Lesen
       int userday, usermonth, useryear;
       if (!InitializeData(out userday, out usermonth, out useryear))
           return;

       //Verarbeiten
       int[] monthdays = { 31, useryear % 4 == 0 ? 28 : 2931303130313130313031 };
       int sumOfDays = 0;
       for (int i = 0; i < usermonth - 1; i++)
           sumOfDays += monthdays[i];
       sumOfDays += userday;

       //Schreiben
       lblAusgabe.Text = "Der " + userday.ToString() + "." + usermonth.ToString() + " ist der " + sumOfDays.ToString() + ". Tag im Jahr " + useryear.ToString();
       lblAusgabe.Visible = true;
}
private bool InitializeData(out int userday, out int usermonth, out int useryear)
{
       bool Converted = true;
       if (!int.TryParse(txtDays.Text, out userday) || userday < 1 || userday > 31)
       {
           MessageBox.Show("Ungültiger Tag!");
           txtDays.Text = "";
           Converted = false;
       }
       if (!int.TryParse(txtMonth.Text, out usermonth) || usermonth < 1 || usermonth > 12)
       {
           MessageBox.Show("Ungültiger Monat!");
           txtMonth.Text = "";
           Converted = false;
       }
       if (!int.TryParse(txtYear.Text, out useryear))
       {
           MessageBox.Show("Ungültiges Jahr!");
           txtYear.Text = "";
           Converted = false;
       }
       if (!Converted)
           lblAusgabe.Text = "";
       return Converted;
}
Nemag
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 132
Erhaltene Danke: 2



BeitragVerfasst: Fr 23.04.10 07:35 
Servus

zum Code an sich will ich jetzt mal nichts sagen, nur zur Schaltjahrberechnung (hab mir jetzt nicht alles durch gelesen - vielleicht hat es ja auch schon jemand geschrieben)

Schaltjahre sind alle Jahre die restlos durch 4 geteilt werden können ohne die, die durch 100 teilbar aber nicht durch 400 teilbar sind.

quasi 1900 war keins, 2000 war eins und 2100 wird wieder keins.

aber das nur am Rande.
ThomAlex Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58

Windows 7
C# (VS08) Games via XNA (privat) oder WinForms (Schule)
BeitragVerfasst: Mo 26.04.10 18:51 
@Nemag:
Zitat:

Schaltjahre sind alle Jahre die restlos durch 4 geteilt werden können ohne die, die durch 100 teilbar aber nicht durch 400 teilbar sind.

ausblenden C#-Quelltext
1:
int[] monthdays = { 31, useryear % 4 == 0 ? 28 : 2931303130313130313031 };					

Im zweiten Element, dem Februar, ist deine Anmerkung längst erfüllt worden.
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mo 26.04.10 19:29 
user profile iconThomAlex hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden C#-Quelltext
1:
int[] monthdays = { 31, useryear % 4 == 0 ? 28 : 2931303130313130313031 };					

Im zweiten Element, dem Februar, ist deine Anmerkung längst erfüllt worden.

Wie bitte?
* Bei useryear = 1900 ist mod4 gleich 0, dann also 28 Tage. Korrekt.
* Bei useryear = 1901 ist mod4 gleich 1, dann also 29 Tage. Falsch.
* Bei useryear = 1902 ist mod4 gleich 2, dann also 29 Tage. Falsch.
* Bei useryear = 1903 ist mod4 gleich 3, dann also 29 Tage. Falsch.
* Bei useryear = 1904 ist mod4 gleich 0, dann also 28 Tage. Falsch.

Du müsstest also zumindest 28 und 29 vertauschen. Aber auch dann fehlen die Bedingungen mod 100 und mod 400.

Jürgen
ThomAlex Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 58

Windows 7
C# (VS08) Games via XNA (privat) oder WinForms (Schule)
BeitragVerfasst: Mi 28.04.10 22:37 
Wenn mans genau nimmt schon, aber die Gregorianische Regel gilt nur bis 1582 und diese wollte ich weglassen und simpel einfach die julianische Regel, die nur besagt Ein Jahr ist ein Schaltjahr, wenn die Division durch 4 keinen Rest ergibt, weiter nichts, nehmen.
Nemag
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 132
Erhaltene Danke: 2



BeitragVerfasst: Do 29.04.10 09:47 
user profile iconThomAlex hat folgendes geschrieben Zum zitierten Posting springen:
Wenn mans genau nimmt schon, aber die Gregorianische Regel gilt nur bis 1582 und diese wollte ich weglassen und simpel einfach die julianische Regel, die nur besagt Ein Jahr ist ein Schaltjahr, wenn die Division durch 4 keinen Rest ergibt, weiter nichts, nehmen.


Also wenn man es schon genau nimmt gilt die Gregorianische Regel ab 1582 und nicht bis. Übrigens gibt es dafür diverse Normen ISO 8601 (die deutsche dazu weiß ich spontan nicht und war jetzt zu faul zu googln).

Ich hoffe du hast den von Jürgen beschriebenen Fehler beim Zuweisungoperator wenigstens getauscht ;-)
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 29.04.10 17:18 
user profile iconNemag hat folgendes geschrieben Zum zitierten Posting springen:
Normen ISO 8601 (die deutsche dazu weiß ich spontan nicht

Ganz einfach: EN 28601 (und europäische Normen sind auch deutsche Normen). Jürgen