Alter in Tagen berechnen
-
Nachtrag:
ich habe die Reihen folge der ersten beiden Aufrufe in MAIN geändert:
Es wird immer nur der erste Aufruf korrekt abgehandelt !!!!!
-
Ich habe etwas gefunden, obwohl ich mir nciht wrklären kann , warum es so ist.
ein Blick in time.h zeigte, daß es ja auch sec/min/std gibt
(Frage, was bedeutet DST in der Structur ???
ich habe also für beide struct diese werte = 0 gesetzt.zeitAlt->tm_year = jahrAlt - 1900; zeitAlt->tm_mon = monatAlt - 1; // oder +1 ? zeitAlt->tm_mday = tagAlt; zeitAlt->tm_sec = 0; /* Seconds. [0-60] (1 leap second) */ zeitAlt->tm_min = 0; /* Minutes. [0-59] */ zeitAlt->tm_hour = 0; /* Hours. [0-23] */
Dies bracht schon mal für die Aufrufe 2 ff Secunden-Werte (mktime) ungleich 0
Allerdings als double.2.) der Rückgabewert wurde in (int) geändert, und ein gerundeter wert zurückgegeben
return (int) (( tage *10 +.5)/10);
3.) die ergebnisse:
a)
1.1.2003 --- 1.4.2003
SekAlt 1041375600 SekNeu 1049151600
Alter in Tagen ( 20030101 - 20030401 ) ist 90b)
1.1.2003 --- 1.4.2003
SekAlt 1041375600 SekNeu 1049151600
Alter in Tagen ( 20030101 - 20030401 ) ist 90c)
1.1.2003 --- 1.4.2003
SekAlt 1041375600 SekNeu 1049148000
Alter in Tagen ( 20030101 - 20030401 ) ist 90d)
1.1.2004 --- 1.4.2004
SekAlt 1072911600 SekNeu 1080770400
Alter in Tagen ( 20040101 - 20040401 ) ist 91Merkwürdig ist nur daß der Wert SekNeu - bei gleichen Eingangsdaten - in c) von denen in a) und b) abweicht.
Wieso kalppt es, wenn man sec/min/h explizit auf 0 setzt ?
Ich kann mir nur erklären, daß der g++ merkt, daß die routine mehrfach aufgerucfen wird, und deshalb die structur alloziert lässt ???ich arbeite unter Suse 8.0 mit g++.
Könnt ihr mal auf anderen Systemen den gleichen Test durchführen ?
( ! ich habe die Datumsstring zuletzt gegenüber den in meinem Code-Posting geändert !)Gruß Hanns
-
Hi
DST ist für die Beschreibung von Zeitzonen also +-Stunden von lokaler Zeit.
-
damit du alle felder der struktur tm* zeitAlt
auf null setzt mach ein memset( zeitAlt, 0, sizeof( *zeitAlt ) ).// jetzt Zeitstruktur bilden, und mit dem ersten Wert auffüllen struct tm *zeitAlt; zeitAlt = (struct tm *) malloc ( sizeof (struct tm ) ); memset( zeitAlt, 0, sizeof( *zeitAlt ) ); // hier musst du evtl. ein bisshen rumspielen zeitAlt->tm_year = jahrAlt - 1900; zeitAlt->tm_mon = monatAlt - 1; // oder +1 ? zeitAlt->tm_mday = tagAlt; printf( "Structur alt : %i.%i.%i\n",zeitAlt->tm_year,zeitAlt->tm_mon,zeitAlt->tm_mday);
-
DAnke für den Hinweis,
aber schau Dir doch bitte mal die Unterschiedliechen ergebnisse für 3 x gleich Parameter an !
Wie kann das sein ????Hanns
-
entelechie: den rückgabewert von malloc castet man nicht.
-
HI
Ich caste den immer, es gibt auch compiler die dich anmeckern wenn du es nicht machst. malloc gibt *void zurück,und wenn ich es einem char* zuweisen will, caste ichs drauf. Was soll daran falsch sein?
-
wurde hier schon tausend mal diskutiert. will ich nicht nochmal machen.
-
Hi
Kann ja sein hab ich noch nich mitbekommen. Würd gerne wissen was daran falsch ist. Man lernt ja nie aus. Vielleicht haste ja n link auf den Thread!?
-
-
Noch besser währe, wenn du dir mal überlegst wie man das ganze mal ohne time etc von Hand aufbaut.
Hab selber sowas damals noch in Q-Basic geschrieben.
Fördert die Logik die dahinter steckt.
-
Hi
thx @helm
-
Hey jungs, darf ich Euch mal auf das eigentliche Problem hinweisen ?
- Es sollte das ALter in Tagen berechnet werden.
- wir haben die struct time dazu verwendet
- wenn die struct vor Verwendung nicht in einen definierte Zustand versetzt wird ( am einfachsten memeset() ) gibt es unvorhersehbare Ergebnisse.
Dann hat sich eine weiteres Problem -und das ist noch ungklärt- ergeben.
4.) rufe ich die Funktion mehrmals hintereinande mit den gleichen Werten auf, liefert die Umwandlung in Uhren-Ticks unterschiedliche Werte
Wieso ? DIe Anzahl sekunden ab 1.1.1970 bis heute ( 0Uhr/0Minuten/0Sekunden) sind doch immer identisch, egal wie oft ich sie bestimme ? oder liege ich da falsch?
Ich compilier mit dem g++ unter Linux.
hier noch mal der Testcode in der aktuellen form/*********************************************** * tage.cc * berechnen des Alters in Tagen * parm 1 string datum_Al, string datum_Neu ************************************************ */ #include <vector> #include <iostream> #include <fstream> #include <string> #include <iomanip> #include <stdlib.h> #include <stdio.h> #include <time.h> int AlterInTagen ( string datum_Alt, string datum_Neu ) { // datum_x = "JJJJMMTT" wird nicht geprüft !!!! // und in Tag/Monat/Jahr umwandeln int jahrAlt,jahrNeu,monatAlt,monatNeu, tagAlt,tagNeu; jahrAlt = atoi (datum_Alt.substr(0,4).c_str() ); jahrNeu = atoi (datum_Neu.substr(0,4).c_str() ); monatAlt = atoi (datum_Alt.substr(4,2).c_str() ); monatNeu = atoi (datum_Neu.substr(4,2).c_str() ); tagAlt = atoi (datum_Alt.substr(6,2).c_str() ); tagNeu = atoi (datum_Neu.substr(6,2).c_str() ); cout << tagAlt << "." << monatAlt << "." << jahrAlt << " --- " << tagNeu << "." << monatNeu << "." << jahrNeu << endl;; // printf( "%i.%i.%i -- %i.%i.%i\n", tagAlt, monatAlt,jahrAlt, tagNeu,monatNeu , jahrNeu); // jetzt Zeitstruktur bilden, und mit dem ersten Wert auffüllen struct tm *zeitAlt; zeitAlt = (struct tm *) malloc ( sizeof (struct tm ) ); if ( zeitAlt == NULL ) { cout << "Fehler bei malloc() zeitAlt !" << endl; return 0; } // hier musst du evtl. ein bisshen rumspielen zeitAlt->tm_year = jahrAlt - 1900; zeitAlt->tm_mon = monatAlt - 1; // oder +1 ? zeitAlt->tm_mday = tagAlt; zeitAlt->tm_sec = 0; /* Seconds. [0-60] (1 leap second) */ zeitAlt->tm_min = 0; /* Minutes. [0-59] */ zeitAlt->tm_hour = 0; /* Hours. [0-23] */ // printf( "Structur alt : %i.%i.%i\n",zeitAlt->tm_year,zeitAlt->tm_mon,zeitAlt->tm_mday); cout << "Structur alt :" << zeitAlt->tm_year << "-" << zeitAlt->tm_mon<< "- " << zeitAlt->tm_mday << endl; // jetzt Zeitstruktur bilden, und mit dem zweiten Wert auffüllen struct tm *zeitNeu; zeitNeu = (struct tm *) malloc ( sizeof (struct tm ) ); if ( zeitNeu == NULL ) { cout << "Fehler bei malloc() zeitNeu !" << endl; return 0; } // hier musst du evtl. ein bisshen rumspielen zeitNeu->tm_sec = 0; /* Seconds. [0-60] (1 leap second) */ zeitNeu->tm_min = 0; /* Minutes. [0-59] */ zeitNeu->tm_hour = 0; /* Hours. [0-23] */ zeitNeu->tm_mday = tagNeu; zeitNeu->tm_mon = monatNeu - 1; // oder +1 ? zeitNeu->tm_year = jahrNeu - 1900; // zeitNeu->tm_wday = /* Day of week. [0-6] */ // zeitNeu->tm_yday = /* Days in year.[0-365] */ // zeitNeu->tm_isdst = /* DST. [-1/0/1]*/ // printf( "Structur neu : %i.%i.%i\n",zeitNeu->tm_year,zeitNeu->tm_mon,zeitNeu->tm_mday); cout << "Structur neu :" << zeitNeu->tm_year << "-" << zeitNeu->tm_mon<< "- " << zeitNeu->tm_mday << endl; // zeit in sekunden seit dem 1.1.1970 umwandeln time_t zeitInSAlt = mktime( zeitAlt); time_t zeitInSNeu = mktime( zeitNeu ); cout << "SekAlt " << zeitInSAlt << " SekNeu " << zeitInSNeu << endl; // differenz in sekunden berechnen double diffSekunden = difftime( zeitInSNeu ,zeitInSAlt); double tage = diffSekunden / (3600 * 24); free ( zeitNeu); free( zeitAlt); return ((int) ( tage *10 +.5))/10; } int main () { string alt,neu; alt="20030101"; neu= "20030102"; cout << "Alter in Tagen ( " << alt << " - " << neu << " ) ist " << AlterInTagen( alt, neu )<< endl; neu= "20030401"; cout << "Alter in Tagen ( " << alt << " - " << neu << " ) ist " << AlterInTagen( alt, neu )<< endl; // *************KEIN SchaltJahr********************* alt="20030101"; neu= "20030401"; cout << "Alter in Tagen ( " << alt << " - " << neu << " ) ist " << AlterInTagen( alt, neu )<< endl; // *****************SchaltJahr**** alt="20040101"; neu= "20040401"; cout << "Alter in Tagen ( " << alt << " - " << neu << " ) ist " << AlterInTagen( alt, neu )<< endl; }
Hanns
p.s. Frank, hatt ich auch schon überlegt, aber die Zeit: hättest Du denn den Basic -code noch zum verschenken ?
-
Hab den Code sogar noch in c++ noch gehabt.Ist allerdings auch umständlich gelöst(Tage werden einzeln gezählt ...).
Müsste mir mal ne schnellere Lösung einfallen lassen.
Die Separatorfunktion müsstest du, wenn du keine Trennzeichen im Datum hast eben mit substr ersetzen.#include <conio.h> #include <iostream.h> //Funktion Separator dient zum Auslesen der Tage,Monate,Jahre aus dem string string Separator(string sSourceText,string sSeparator,int iPos); int Anzahltage(string Anfangsdatum,string Enddatum); void main() { string anfang,ende; cout << "Anfangsdatum(tt.mm.jjjj):"; cin >> anfang; cout << "Enddatum(tt.mm.jjjj):"; cin >> ende; cout << "\nDas sind " << Anzahltage(anfang,ende) << " Tage."; getch(); } int Anzahltage(string Anfangsdatum,string Enddatum) { int idatum[2][3],ianztag=0,imon[12]={31,28,31,30,31,30,31,31,30,31,30,31}; string sdatum[2]={Anfangsdatum,Enddatum}; //string in Integerarray übernehmen for(int i=0;i<2;i++) { for(int j=0;j<3;j++) { idatum[i][j]=atoi(Separator(sdatum[i],".",j+1).c_str()); } } //Solange wie Enddatum ungleich Anfangsdatum while(idatum[0][0]!=idatum[1][0]||idatum[0][1]!=idatum[1][1]||idatum[0][2]!=idatum[1][2]) { ianztag++;//Zähler Tage idatum[1][0]--;//Enddatum Tage runterzählen if(!idatum[1][0])// Wenn Tag < 1 { idatum[1][1]--;// Monat runterzählen if(!idatum[1][1])// Wenn Monat < 1 { idatum[1][1]=12; //Monat=12 idatum[1][2]--; //Jahr runterzählen } idatum[1][0]=imon[(idatum[1][1]-1)];// Tage des Vormonats übernehmen //Wenn Schaltjahr Februar 29 Tage if(idatum[1][1]==2)if((idatum[1][2]%4==0&&idatum[1][2]%100!=0)||idatum[1][2]%400==0)idatum[1][0]++; } } return ianztag;//Anzahl Tage zurück } string Separator(string sSourceText,string sSeparator,int iPos) { int x; while(iPos--) x=1+sSourceText.find(sSeparator.c_str(),x); return sSourceText.substr(x,sSourceText.find(sSeparator.c_str(),x)-x); }