Servus Leute!
Ich möchte ein C-Programm erstellen welches mir meinen Biorythmus ausgibt und dazu benötige ich eine Funktion welche mir die Anzahl meiner bereits gelebten Tage ausgibt.
z.B.: Geburtsdatum 14.3.1990
heutiges Datum 18.3.2009
Nun soll die Anzahl der gelebten Tage durch eine Funktion berechnet werden.
Hier mein derzeitiges fehlerhaftes Ergebnis:
Code:
int tage(int t1, int m1, int j1, int t2, int m2, int j2){
int dif=0,difm=0;
int schalt=0;
if(t1>t2){
dif+= t1-t2;
if(m2>m1)
difm=m2-m1-1;
else
difm=12-(m1-m2)-1;
}
else{
dif+= t2-t1;
if(m2>m1)
difm=m2-m1;
else
difm=12-(m1-m2);
}
switch(difm){
case 11: dif+=30;
case 10: dif+=31;
case 9: dif+=30;
case 8: dif+=31;
case 7: dif+=31;
case 6: dif+=30;
case 5: dif+=31;
case 4: dif+=30;
case 3: dif+=31;
case 2: dif+=29;
case 1: dif+=31;
break;
default: return 1;
}
schalt=(j2/4) + (j2/400) + ((j1-1)/100) - (j2/100) - ((j1-1)/4) - ((j2-1)/400);
dif+=schalt*366;
if(m1 >= m2 && t1>t2)
dif+=(j2-j1-schalt-1)*365;
else
dif+=(j2-j1-schalt)*365;
return dif;
Bei t1,m1,j1 handelt es sich um das Geburtsdatum bei t2,m2,j2 um das heutige Datum.
Bitte um tatkräftige Hilfe/Unterstützung.
Geändert von incredible-olf (18.03.2009 um 18:51 Uhr).
18.03.2009, 19:06
Threadersteller
PowidL
Konnte den Fehler leider nicht ausfindig machn. Geh das schon seit stunden durch .
Wenn ich den Fehler wüsste würde es mir schon sehr sehr viel weiterhelfen.
18.03.2009, 19:11
incredible-olf
Ich dachte du bekämst eine Fehlermeldung
In wiefern weicht das Programmergebnis denn vom gewünschten ab?
18.03.2009, 19:13
Threadersteller
PowidL
Nein Nein, habe weder Errors noch Warnings. Nur gibt es mir Zahlen aus die nicht korrekt sind. Bei meinem Geburtsdatum weicht er nur um 20 Tage ab und bei manch anderen gibt er mir sogar nur 1 als Ergebnis aus.
Ein reines Logikproblem also.
//EDIT: Ein Problem was ich hier selber sehe ist in der switch-case der 2. Monat. Hier benötige ich eig eine Schaltjahres formel aber leider habe ich keine Ahnung was für eine Jahreszahl ich hier überhaupt einsetzn soll da die Jahre in dieser Anweisung ja keine konkrete Rolle spielen.
Geändert von PowidL (18.03.2009 um 19:17 Uhr).
18.03.2009, 19:31
incredible-olf
Versuchs mal so:
1. Du definierst für jeden Monat eine integer Variable mit der Anzahl der Tage, für den Februar nimmst du 29.
2. Du bestimmst wieviele Tage im Geburtsmonat nach dem Geburtstag noch bleiben.
3. Du erhälst mit diesen Tagen und den Monaten die danach noch folgen schonmal die gelebten Tage im Geburtsjahr.
4. Du rechnest alle Jahre nach dem Geburtsjahr bis zu einem Jahr vor dem aktuellen zusammen, und multiplizierst dies mit 365.
5. Du bestimmst über das aktuelle Datum die Tage die dieses Jahr schon abgelaufen sind (also alle abgelaufenen Monate plus die Tage aus dem aktuellen Monat).
6. Du addierst jetzt die Tage aus dem Geburtsjahr, das Ergebnis von Schritt 4, und die Tage aus Schritt 5 zusammen. Jetzt hast du schonmal die gelebten Tage mit dem Fehler von Schaltjahren.
7. Um zu ermitteln welches Jahr ein Schaltjahr ist musst du prüfen ob der Rest der Teilung der Jahreszahl durch 4 gleich 0 ist. (Wie das genau in C geht kann ich dir nicht sagen, schau dich mal nach "modulo" um). Wenn das zutrifft ist es ein Schaltjahr, dann kannst du einen Tag von der Summe der Tage abziehen. Wenn der Geburtstag im März oder später liegt musst du das Geburtsjahr nicht mit prüfen. Wenn das aktuelle Datum vor dem 29. Februar liegt musst du dieses nicht mit prüfen.
18.03.2009, 19:39
Threadersteller
PowidL
Ich werde mein bestes geben und schauen was dabei rauskommt!
Melde mich nachher mit Ergebenis wieder.
Danke derweil!
//EDIT:
So nochmal geedditet!
Stimmt jetzt fasst genau...leider nur fasst.
Verschätzt sich jetz bei jedem x-beliebigen Datum ca um 2-5 Tage
Code:
int tage(int t1, int m1, int j1, int t2, int m2, int j2){
int dif=0,s1;
int schalt=0;
for(;j1+1<j2-1;j1++){
dif+=365;
}
j1=s1;
switch(12-m1){
case 11: dif+=30;
case 10: dif+=31;
case 9: dif+=30;
case 8: dif+=31;
case 7: dif+=31;
case 6: dif+=30;
case 5: dif+=31;
case 4: dif+=30;
case 3: dif+=31;
case 2: dif+=28;
case 1: dif+=31;
break;
default: return 1;
}
switch(m1){
case (1 || 3 || 5 || 7 || 8 || 10 || 12): dif+=31-t1;
break;
case 2: dif+=28-t1;
break;
default: dif+=30-t1;
}
switch((m2-1)){
case 11: dif+=30;
case 10: dif+=31;
case 9: dif+=30;
case 8: dif+=31;
case 7: dif+=31;
case 6: dif+=30;
case 5: dif+=31;
case 4: dif+=30;
case 3: dif+=31;
case 2: dif+=28;
case 1: dif+=31;
break;
default: return 1;
}
dif+=t2;
schalt=(j2/4) + (j2/400) + ((j1-1)/100) - (j2/100) - ((j1-1)/4) - ((j2-1)/400);
dif+=schalt;
return dif;
}
Geändert von PowidL (18.03.2009 um 20:57 Uhr).
19.03.2009, 03:14
LordOfThePings
Warum nimmst du nicht einfach die in C vorhandenen Funktionen? ]
Interessant dürfte vor allem difftime() sein, die Sekunden kriegste dann ja einfach in Tage umgerechnet.
Du musst da also zwei tm structs anlegen, die mit deinen beiden Daten füllen, mit mktime umwandeln in time_t, und die dann in difftime geben.
19.03.2009, 08:57
Threadersteller
PowidL
Eine sehr interessante Lösung mit diftime(), nur wüsst ich nicht wie ich es richtig umsetzn soll das ich beide Daten in Sekunden umgerechnet bekomme.
Ein Beispiel wäre nett^^
Versuche mein Bestes.
19.03.2009, 18:54
LordOfThePings
In Sekunden umrechnen musst du ja gar nicht. Schau dir mal die struct tm an, da kannste einfach ein Datum ablegen, und dass dann mit mktime() umrechnen lassen. Die Ausgabe davon (ein time_t) kannste dann in difftime() verwenden. Brauchst du auch nur einmal machen, weil time() dir die aktuelle Zeit gleich als time_t gibt (du willst ja die Tage bis jetzt, also kannst dir das zweite Datum berechnen sparen).
22.03.2009, 20:56
Threadersteller
PowidL
Danke das klingt einleuchtend.
Verstehe zwar die Syntax noch nicht ganz, denke aber, dass ich schon hinbekommen werde. Denn damit würd ich mir schon einiges sparen.
Die Funktion welche ich oben gepostet habe funktioniert, aber leider nur ungenau. Habe erfahren das es nur schwer geht genauer zu berechnen, aber ich denke doch das es nicht wirklich schwer sein kann alle Tage auszurechnen welche zwischen 2 Daten liegen.