Alter in Tagen berechnen



  • 😕 Ich bin mir sicher, schon mal eine Antwort auf diese Frage gelesen zu haben, kann aber nichts mehr dazu finden:
    ALso frage ich Euch:

    Wie kann ich aus zwei Datumsangaben, die als string in der Form "JJJJMMTT" vorliegen, das Alter in Tagen bestimmen ?

    Danke Hanns



  • Durch wandeln in einen Datumstypen der vergangene Tage seit xxx enthält.
    Dann kann man einfach alter_tage = aktuelles_datum-geburtsdatum; machen



  • hi dreaddy

    Durch wandeln in einen Datumstypen der vergangene Tage seit xxx enthält.

    und wie das geht, weiß ich halt nicht ??

    Dann kann man einfach alter_tage = aktuelles_datum-geburtsdatum; machen

    Diese dachte ich mir, ( aber wie ?) .

    Würdest Du mir evtl ein beispiel geben, oder einen Link ?
    Danke Hanns

    [ Dieser Beitrag wurde am 18.06.2003 um 12:52 Uhr von ^Hanns editiert. ]



  • ungetestet:

    #include <time.h>
    #include <string.h>
    ...
    struct tm zeit;
    memset( &zeit, 0, sizeof( struct tm ) );
    /* hier musst du evtl. ein bisshen rumspielen*/
    zeit.tm_year = jahr - 1900;
    zeit.tm_mon  = monat - 1; /* oder +1 ? */
    zeit.tm_mday = tag;
    
    /* das gleiche fuer eine zeit2 */
    
    /* zeit in sekunden seit dem 1.1.1970 umwandeln */
    time_t zeitInS1 = mktime( zeit )
    time_t zeitInS2 = mktime( zeit2 ); 
    
    /* differenz in sekunden berechnen */
    double diffSekunden = difftime( zeitInS1, zeitInS2 );
    int tage = diffSekunden / (3600 * 24);
    


  • danke, ich versuchsmal, und zeig dann das Ergebnis ??
    Hanns



  • So, ich hab mal was versucht,
    leider klappt es nur mit dem ersten "Datum".
    Da die Tage negativ sind, müssen die Parameter von difftime() vertauscht werden!
    verwende ich bei der Kontrollanzeige für zeitInSAlt und zeitInSNeu printf(), ergibt der Wert für zeitInSAlt NaN ( not a Number)

    und nun stehe ich wieder da, und weiß nicht weiter!
    Ihr ?

    Hanns

    ( ich weiß, das cout zu c++ gehört !)
    Hier der Code

    ***********************************************
    * tage.cc
    * berechnen des Alters in Tagen
    * parm 1 string datum_Al, string datum_Neu
    ************************************************
    */
    
    #include <vector.h>
    #include <time.h>
    #include <iostream.h>
    #include <fstream.h>
    #include <string>
    #include <iomanip>
    #include <stdlib.h>
    #include <stdio.h>
    
    double 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() );
    
     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 ) );
    // 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);
    
    // jetzt Zeitstruktur bilden, und mit dem zweiten Wert auffüllen
    struct tm *zeitNeu;
    zeitNeu = (struct tm *) malloc ( sizeof (struct tm ) );
    // hier musst du evtl. ein bisshen rumspielen
    zeitNeu->tm_year = jahrNeu - 1900;
    zeitNeu->tm_mon  = monatNeu - 1; // oder +1 ?
    zeitNeu->tm_mday = tagNeu;
    
     printf( "Structur neu : %i.%i.%i\n",zeitNeu->tm_year,zeitNeu->tm_mon,zeitNeu->tm_mday);
    
    // 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( zeitInSAlt, zeitInSNeu );
    double tage = diffSekunden / (3600 * 24);
    return tage;
    }
       int main () {
    string alt,neu;
    alt="20030601";
    neu= "20030621";
    
    cout << "Alter in Tagen ( " << alt << " - " << neu << " ) ist " << AlterInTagen( alt, neu )<< endl;
    neu= "20030611";
    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;
    }
    


  • Hi

    Rechne doch einfach mit dem julianischen Datum.
    Ich hab diese ganzen Sachen für windows in zwei Klassen implementiert die sich an der MFC CTime orientieren. Müsste aber eigentlich auch für unix funktionieren nach einem kleinen Porting. Also wenn du die Klasse benutzen willst sag mir bescheid.

    Das prinzip ist einfach du rechnest einfach das gregorianische Datum ins julianische um und kannst nun einfach tage subtrahieren.



  • Original erstellt von prolog:
    **Hi

    Rechne doch einfach mit dem julianischen Datum.
    Ich hab diese ganzen Sachen für windows in zwei Klassen implementiert die sich an der MFC CTime orientieren..**

    ich bin unter linux. Fenster o.ä dinge brauche ich nicht, da das ganze eine HTML-Seite wird.

    **

    Müsste aber eigentlich auch für unix funktionieren nach einem kleinen Porting. Also wenn du die Klasse benutzen willst sag mir bescheid.**

    Bescheid (grins)

    **

    Das prinzip ist einfach du rechnest einfach das gregorianische Datum ins julianische um und kannst nun einfach tage subtrahieren.

    **

    OK, aber dafür gibt es unter linux auch routinen ??
    Abgesehen davon, warum klappt es denn nicht mit difftime ?

    Danke erst einmal, und weitere Anregungen erhoffend
    Hanns

    [ Dieser Beitrag wurde am 19.06.2003 um 22:13 Uhr von ^Hanns editiert. ]



  • hans ich verstehe dein problem nicht.
    mach doch einfach:

    double diffSekunden = (zeitInSAlt > zeitInSNeu )?
            difftime( zeitInSAlt, zeitInSNeu ) : difftime( zeitInSNeu, zeitInSAlt ) ;
    

    draus, dann stimmts.

    noch was:
    programmiere c oder c++, mische aber auf keinen fall.
    also entweder printf oder cout.
    wenn du cout etc verwendest benutz die header ohne h
    (sind im namespace std)
    also:

    #include <vector>
    #include <ctime>
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    #include <iomanip>
    #include <cstdlib>
    #include <cstdio>
    
    using namespace std;
    


  • DAnke erstmal für den Tipp mit den Headern.
    Ich echt wird es eine Routine für c++ werden, aber da es eigentlich aus dem ansi-c stammt, dacht ich, hier richtig zu sein.

    Mein Problem ist nicht die Reihenfolge der Parameter übergabe ( vom 16. minus 1. ergibt es richtig 10Tage, vom 1. minus 16. MINUS 10 Tage. damit könnt ich leben, ( oder es auch richtig machen ) aber.
    Wie Du siehst, habe ich mehrere AUfrufe der routine aus main gestartet, und ich bekomme nur beim ersten AUfruf ein "richtiges" ergebnis. alle folgenden Aufrufe ergeben 0-Tage.
    gebe ich es über printf aus, kommt die Meldung, daß der erste Wert nan sei.
    - mit den Werten alt="20030601"; neu= "20030621"; klappt es,
    - setze ich neu= "20030611"; gibt es 0.
    - mit alt="20040101";neu= "20040401"; ( Schaltjahr !) ergibt 91
    (stimmt laut Kalender, wenn der 1.4.04 nicht mitgerechnet wird!)
    - mit alt="20030101";neu= "20030401"; ( kein Schaltjahr !) ergibt 90

    - sobald ich die beiden letzen nacheinander aus main aufrufe, hat der zweite wert wieder 0! 😕

    Ansonsten hab ich die #includes wie folgt geändert
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <iomanip>

    // stecken die nächasten drei in einer ohne .h ?
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>

    Hanns

    p.s.: ich muss den speicher doch am Ende der Funktion nicht frei geben? . die beiden "zeit*" werden coh nur innerhalb der routine verwendet, und bei Ende freigegeben ??

    [ Dieser Beitrag wurde am 19.06.2003 um 23:02 Uhr von ^Hanns editiert. ]



  • Hi

    ich bin unter linux. Fenster o.ä dinge brauche ich nicht, da das ganze eine HTML-Seite wird.

    @^Hanns

    Nun die klasse hat nichts mit fenstern zu tun. Ich sagt lediglich, dass ich mich an der Funktionalität von CTime orientiert hab. Intern ist das auch nur n time_t. Aber naja.

    🙂



  • Nun die klasse hat nichts mit fenstern zu tun. Ich sagt lediglich, dass ich mich an der Funktionalität von CTime orientiert hab. Intern ist das auch nur n time_t. Aber naja.

    Könntest Du denn Deine Routine mal mit meinen Werten versuchen. Siehe meine Nachrichten von eben ( an entelche)
    Hanns



  • HI

    jepp, probier ich gleich ma aus. Poste dann morgen das Ergebnis.



  • 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 90

    b)
    1.1.2003 --- 1.4.2003
    SekAlt 1041375600 SekNeu 1049151600
    Alter in Tagen ( 20030101 - 20030401 ) ist 90

    c)
    1.1.2003 --- 1.4.2003
    SekAlt 1041375600 SekNeu 1049148000
    Alter in Tagen ( 20030101 - 20030401 ) ist 90

    d)
    1.1.2004 --- 1.4.2004
    SekAlt 1072911600 SekNeu 1080770400
    Alter in Tagen ( 20040101 - 20040401 ) ist 91

    Merkwü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

    @helm

    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?


Anmelden zum Antworten