Entwickler-Ecke
Basistechnologien - Gedankenproblem beim Datumsvergleich
coolace - Mo 01.09.08 14:12
Titel: Gedankenproblem beim Datumsvergleich
Hy,
ich habe folgendes Problem, ich habe eine List<daten> erstellt und ich möchte aus dieser Liste
das nächste Geburtstagskind herausfinden. Die Liste ist sortiert. Aber irgendwie klappt das unten nicht
so ganz mit der Ausgabe der richtigen nächsten Person
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:
| DateTime aktuell = DateTime.Now; foreach (daten temps in liste) { lbox.Items.Add(temps.ToString()); } foreach (daten tempi in liste) {
if (tempi.Gebdatum.Month >= aktuell.Month) { for (int i = 0; i < liste.Count; i++) { if (tempi.Gebdatum.Day < liste[i].Gebdatum.Day && liste[i].Gebdatum.Month > aktuell.Month) { txtage.Text = tempi.Alter(); txtgeburtstag.Text = tempi.Gebname; } } } } |
Danke und Gruß
Coolace
Kha - Mo 01.09.08 14:20
"Irgendwie" ist nie eine gute Fehlerbeschreibung.
Du kannst zwei DateTimes direkt miteinander vergleichen, die innere Schleife brauchst du also gar nicht. Außerdem macht es wohl keinen Sinn, nach einem Treffer die Suche fortzusetzen ;).
coolace - Mo 01.09.08 14:28
Sorry, das Problem ist das wenn andere datums dazwischen sind ich dann auf die Monate zurückgreifen muss
z.B.
02.04.1955 detlef
08.02.1963 anna
09.10.1973 fred
14.07.1984 anna2
14.10.1986 diem
10.10.1990 fred
in dieser sortierten Liste währe 09.10.1973 fred der richtige Geburtstagskandidat aber dies klappt nicht er nimmt lieber
den letzen fred her.
darum dachte ich ich vergleich erstmal alle in der Liste mit dem aktuellen Monat, größer oder gleich, danach war der
Gedanke brauch für die richtige Person wenn mehrere im selben Monat geburtstag haben ja immer den mit dem kleinsten Tag.
Das klappt nicht,
coolace - Mo 01.09.08 16:16
Hy,
hab die geschichte mal aus einem frühreren Thread versucht anzupassen
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| daten naechster = null; DateTime aktuell = DateTime.Now; foreach (daten temps in liste) { lbox.Items.Add(temps.ToString()); } for (int i = 0; i < liste.Count; i++) { DateTime compare = new DateTime(aktuell.Year,liste[i].Gebdatum.Month, liste[i].Gebdatum.Day); if ((compare.CompareTo(aktuell) >= 0) && (aktuell - compare) < (aktuell - naechster.Gebdatum) ) naechster = liste[i]; } txtage.Text = naechster.Alter(); txtgeburtstag.Text = naechster.Gebname; } |
aber irgendwo ist hier noch ein Gedankenfehler, er zeigt gar nichts an?
LG
CoolAce
Erichgue - Mo 01.09.08 16:29
coolace hat folgendes geschrieben: |
Hy,
hab die geschichte mal aus einem frühreren Thread versucht anzupassen
...
aber irgendwo ist hier noch ein Gedankenfehler, er zeigt gar nichts an?
LG
CoolAce |
Hallo CoolAce
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| DateTime date; DateTime dateFound = DateTime.MaxValue; int foundIndex = -1; DateTime foundDate = DateTime.Now;
for (int i = 0; i < listBox1.Items.Count; i++) { date = DateTime.Parse(listBox1.Items[i].ToString()); date = new DateTime(DateTime.Now.Year, date.Month, date.Day); if ((date >= DateTime.Now) && (date < dateFound)) { dateFound = date; foundIndex = i; } } |
foundIndex wäre dann dein Object!
Ich habes mit einer Stringlist und deinen Datumswerten versucht. Klappt wunderbar!
coolace - Mo 01.09.08 16:56
hy
vielen Dank für deine Mühe, hab aber noch das problem das ich es nicht richtig umsetzen kann,
entweder nicht mein Tag heut oder ich seh den Wald vor lauter Bäumen nicht mehr.
Ich hab das komplette Projekt mal angehängt, könntest du mal drüberschauen was ich hier falsch mach?
Danke und Gruß
Coolace
Kha - Mo 01.09.08 17:41
Dein ursprünglicher Ansatz war doch fast richtig, du hättest nur noch das hier umsetzen müssen:
Kha hat folgendes geschrieben: |
"Irgendwie" ist nie eine gute Fehlerbeschreibung.
Du kannst zwei DateTimes direkt miteinander vergleichen, die innere Schleife brauchst du also gar nicht. Außerdem macht es wohl keinen Sinn, nach einem Treffer die Suche fortzusetzen ;). |
coolace - Mo 01.09.08 17:44
Das Problem ist das der erste Treffer ja nicht der richtige sein muss, da danach noch weitere richtige Treffer sein können wo das Datum des Monats kleiner ist als der des ersten Treffers
Kha - Mo 01.09.08 17:47
Tut mir leid, wenn sich etwas verändert hat, aber in deinem letzten Thread war deine Liste noch aufsteigend sortiert :nixweiss: .
coolace - Mo 01.09.08 17:53
Die Sortierung hat ja gepasst nach meinem letzten Thread, nur das Problem ist mit den Jahreszahlen
z.B. 12.10.1963 anna
08.01.1966 tanja
10.10.1990 lenz
11.10.1991 die
hier wäre der richtig vom heutigen Datum ausgehend der lenz da er vom Monat her größer als 9 ist und vom Tag
der kleinste in dem Monat
sorry für meine verwirrenden Formulierungen aber ich bastel schon seit Tagen dran rum
Kha - Mo 01.09.08 18:03
Kha hat folgendes geschrieben: |
Du kannst zwei DateTimes direkt miteinander vergleichen, die innere Schleife brauchst du also gar nicht. |
Ich weiß wirklich nicht, wie ich das noch umformulieren soll :nixweiss: , bei Erichgue hättest du es auch schon sehen sollen.
Na gut, ich versuch's: Tag und Monat brauchen dich doch überhaupt nicht zu interessieren, du willst einfach nur
das erste Datum, das später als heute ist.
lothi - Mo 01.09.08 20:12
Hallo
Zitat: |
a gut, ich versuch's: Tag und Monat brauchen dich doch überhaupt nicht zu interessieren, du willst einfach nur das erste Datum, das später als heute ist. |
Ich glaube schon da ja drum geht welcher Geburtstag am nächsten am heutigen Datum liegt.
Liste mit Geburtsdatum ==> sortierte Liste mit Geburtsdatum von jetzt weg. In diesem Fall ist ja das Jahr nicht wichtig sondern nur der Tag und der Monat. Also die Differenze von Heute minus Geburtstag ohne Jahr. Das Datum mit dem kleinsten minus Wert ist am nächsten vom Geburtstag. 0 == Heute
Die mit plus sind schon zu alt.
Noch etwas die Sortierung des Alters und die Ausgabe des Geburtstags gehört nicht in den GUI, sondern sollte eine eigene Klasse bilden.
coolace - Mo 01.09.08 22:44
@ Christian S.
Sorry, hab es ja versucht umzusetzen, siehe posting oben aber das Problem ist das ich
es nicht hinbekam auf mein Projekt umzumünzen.
Jetzt hab ich es soweit hinbekommen, bekomm aber eine NullReferenceException, was hab ich falsch gemacht?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| for (int i = 0; i < liste.Count; i++) { DateTime compare = new DateTime(aktuell.Year,liste[i].Gebdatum.Month, liste[i].Gebdatum.Day); <span style="color: red"> if ((compare.CompareTo(aktuell) >= 0) && (aktuell - compare) < (aktuell - naechster.Gebdatum) ) naechster = liste[i]; } txtage.Text = naechster.Alter(); txtgeburtstag.Text = naechster.Gebname; } |
Das ganze bei i = 2 aber der Datensatz ist exakt der selbe wie die anderen ?
Hoffe um Nachsicht und versuch mich zu bessern
Gruß
Coolace
Kha - Mo 01.09.08 23:04
Langsam krieg ich hier die Krise :nut: .
C#-Quelltext
1: 2: 3: 4: 5:
| foreach (daten item in liste) if (item >= DateTime.Today) { break; } |
So. Wenn liste aufsteigend sortiert ist, muss das funktionieren. Keine Widerrede :P .
coolace hat folgendes geschrieben: |
Jetzt hab ich es soweit hinbekommen, bekomm aber eine NullReferenceException, was hab ich falsch gemacht? |
Dann hast du Christians Code wohl nur zur Hälfte übernommen, genauer gesagt
nächster nicht initialisiert. Da die Liste damals aber noch nicht sortiert war, nimm jetzt lieber meinen Code :mrgreen: .
Allerdings sieht es nicht gerade so aus, als ob du Christians Schnipsel verstanden hättest. Vielleicht solltest du doch erst einmal Anfängerliteratur wie das Galileo OpenBook zur Hand nehmen :| .
coolace - Mo 01.09.08 23:09
Hy,
auch wenn meine Fragen verwirrt klingen aber ich denk schon das ich Sie verstanden habe,
So dies ist der Teil meines Projekts wo die Form1 geladen wird und die Funktion mit
der Auswahl aufgerufen wird
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:
| InitializeComponent(); try { lbldate.Text = DateTime.Now.ToLongDateString(); rtfbox.LoadFile(@"E:\Butler\notizen.rtf"); using (FileStream fs = File.OpenRead(@"E:\Butler\geburtstag.xml")) liste = (List<daten>) xs.Deserialize(fs); Geburtstagskind(); } catch (Exception) { MessageBox.Show(this, "Eine der Dateien existiert nicht", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error); if (File.Exists(@"E:\Butler\notizen.rtf")) {
} else { File.Create(@"E:\Butler\notizen.rtf"); }
if (File.Exists(@"E:\Butler\geburtstag.xml")) { } else { File.Create(@"E:\Butler\geburtstag.xml"); } }
public void Geburtstagskind() { daten naechster = null; DateTime aktuell = DateTime.Now; foreach (daten temps in liste) { lbox.Items.Add(temps.ToString()); }
if (liste.Coun >=1) naechster = liste[0]; for (int i = 0; i < liste.Count; i++) { DateTime compare = new DateTime(aktuell.Year, liste[i].Gebdatum.Month, liste[i].Gebdatum.Day); if ((compare.CompareTo(aktuell) >= 0) && (aktuell - compare) < (aktuell - naechster.Gebdatum) ) naechster = liste[i]; }
txtage.Text = naechster.Alter(); txtgeburtstag.Text = naechster.Gebname; } |
Ich hab Sie soweit hinbekommen das Sie ohne Maulen läuft aber er gibt den falschen aus, Tagetechnisch gäbe es bei
mir noch bessere Kandidaten
Sorry
Gruß
Coolace
Christian S. - Mo 01.09.08 23:15
Kha hat folgendes geschrieben: |
Da die Liste damals aber noch nicht sortiert war, nimm jetzt lieber meinen Code :mrgreen: . |
Bringt die Sortierung denn wirklich was, wenn man das nächste Geburtstagskind haben will? In der Sortierung steht der 3.9.1960 vor dem 2.9.1990, aber trotzdem ist letzterer das nächste Geburtstagskind.
coolace - Mo 01.09.08 23:20
Hy,
hab im Anhang einen Screenshot mit den Geburtstagskindern (alles fiktive zwecks Datenschutz)
und da ist der letzt jörg der der genommen wird obwohl der 1 vor jörg der richtige wäre
lothi - Di 02.09.08 08:19
Hallo
So jetzt will ich auch noch mal den Senf dazugeben.
Es ist ja egal ist ob das Geburttagsking 1933 oder 1944 oder 2007 geboren ist, hat es trotzdem heute geburttag. Also ist die Jahrzahl nicht nötig. Da du aber nicht nur Monat und Tag sortieren kannst würde ich jetzt eine neue Liste machen und du gibst jeden Datum die gleich Jahrzahl dann
Heute minus neues Datum = ein TimSpan mit Tagen. Alle Werte die >0 haben den Geburtag schon vorbei == 0 haben heute Geburtstag <0 haben in sovielen Tagen Geburtstag.
Du musst nur gucken das du dann der richtige Name zum richtigen Datum hast. Mit einer SortedList oder SortedDictionary.
Gruss Lothi
Erichgue - Di 02.09.08 09:26
coolace hat folgendes geschrieben: |
hy
vielen Dank für deine Mühe, hab aber noch das problem das ich es nicht richtig umsetzen kann,
entweder nicht mein Tag heut oder ich seh den Wald vor lauter Bäumen nicht mehr.
Ich hab das komplette Projekt mal angehängt, könntest du mal drüberschauen was ich hier falsch mach?
Danke und Gruß
Coolace |
Hallo CoolAce
Gerne!
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:
| public void Geburtstagskind() { txtage.Text = ""; txtgeburtstag.Text = ""; foreach (daten temps in liste) { lbox.Items.Add(temps.ToString()); }
DateTime date; DateTime dateFound = DateTime.MaxValue; int foundIndex = -1; DateTime foundDate = DateTime.Now;
for (int i = 0; i < lbox.Items.Count; i++) { date = DateTime.Parse(lbox.Items[i].ToString()); date = new DateTime(DateTime.Now.Year, date.Month, date.Day);
if ((date >= DateTime.Now) && (date < dateFound)) { dateFound = date; foundIndex = i;
} }
if (foundIndex > -1) { txtage.Text = liste[foundIndex].Alter(); txtgeburtstag.Text = liste[foundIndex].Gebname; } |
Hups! Zu schnell geschossen! So geht es nicht! Warte mal, der richtige Code kommt gleich!
Erichgue - Di 02.09.08 09:38
coolace hat folgendes geschrieben: |
hy
vielen Dank für deine Mühe, hab aber noch das problem das ich es nicht richtig umsetzen kann,
entweder nicht mein Tag heut oder ich seh den Wald vor lauter Bäumen nicht mehr.
Ich hab das komplette Projekt mal angehängt, könntest du mal drüberschauen was ich hier falsch mach?
Danke und Gruß
Coolace |
So, jetzt müßte es passen.
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:
| public void Geburtstagskind() { DateTime date; DateTime dateFound = DateTime.MaxValue; DateTime foundDate = DateTime.Now; daten gebFound = null;
txtage.Text = ""; txtgeburtstag.Text = "";
lbox.Items.Clear(); lbox.BeginUpdate();
foreach (daten temps in liste) { lbox.Items.Add(temps.ToString());
date = temps.Gebdatum; date = new DateTime(DateTime.Now.Year, date.Month, date.Day);
if ((date >= DateTime.Now) && (date < dateFound)) { dateFound = date; gebFound = temps; } }
lbox.EndUpdate();
if (gebFound != null) { txtage.Text = gebFound.Alter(); txtgeburtstag.Text = gebFound.Gebname; }
} |
Wärend du die Liste füllst, kannst du gleich das Geb-Kind ermitteln.
So hast du auch am Schluß das Objekt deines Geb-Kindes und kannst damit weiter arbeiten.
Erich
coolace - Di 02.09.08 14:52
Hy,
vielen vielen Dank an alle die mir hierbei geholfen haben (50 Kästen Bier in die runde stell).
Gruß
Coolace
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!