Über das Datum eine Zeitspanne berechnen



  • Hi,

    ich habe ein blödes Problem, von dem ich nicht weis, wie ich es angehen soll.
    Ich muss anhand von einem Datum eine Zeitspanne ausgehend von einer Uhrzeit
    berechnen:

    Start: 02.08.09 - 12:15:49 Uhr
    Ende: 03.08.09 - 15:00:30 Uhr

    Nun müssen praktisch ja auch ein Schaltjahr und die verschieden langen
    Monate berücksichtigt werden (28/29,30 bzw. 31 Tage im Monat).

    Habt ihr dazu eine Anregung?



  • Die Klassen COleDateTime und COleDateTimeSpan müssten dafür eigentlich geeignet sein, nehme ich an...



  • isabeau schrieb:

    Die Klassen COleDateTime und COleDateTimeSpan müssten dafür eigentlich geeignet sein, nehme ich an...

    Oder eben CTimeSpan.



  • Danke für die Tipps.

    Wie wende ich das richtig an, damit auch korrekt gerechnet wird?
    In diesem Fall wird mir nur 1 Tag 0 Stunden 0 Minuten und 0 Sekunden
    ausgegeben? Die Sekunden werden nicht berücksichtigt??

    CTime t1( 1999, 3, 19, 22, 15, 00 ); // 10:15PM March 19, 1999
    	CTime t2( 1999, 3, 20, 22, 15, 10 ); // 10:15PM March 20, 1999
    	CTimeSpan ts = t2 - t1;  // Subtract 2 CTimes
    
    	LONGLONG totsec = ts.GetTotalSeconds();
    	LONGLONG days=ts.GetDays();
    	long hours = ts.GetHours();
    	long minutes = ts.GetMinutes();
    	long seconds = ts.GetSeconds();
    
    	CString zeitspanne;
    	zeitspanne.Format("%2d Tage %2d Stunden %2d Minuten %2d Sekunden",days,hours,minutes,seconds);
    	MessageBox(zeitspanne,"ergebnis");
    


  • Hmm daylightsaving (CTime Param 7) muss also auch gesetzt sein mit größer 0, damit die
    Stunden richtig gerechnet werden!

    Dann sollte es wie folgt wohl korrekt sein:

    CTime t1( 1999, 3, 9, 15, 14, 00,1 ); // 10:15PM March 19, 1999 und daylightsaving
    	CTime t2( 1999, 3, 29, 22, 15, 19,1 ); // 10:15PM March 20, 1999 und daylightsaving
    	CTimeSpan ts = t2 - t1;  // Subtract 2 CTimes
    /*
    	LONGLONG totsec = ts.GetTotalSeconds();
    	LONGLONG days=ts.GetDays();
    	LONG hours = ts.GetHours();
    	LONG minutes = ts.GetMinutes();
    	LONG seconds = ts.GetSeconds();
    */
    
    CString erg = ts.Format( "%D Tage %H Stunden %M Minuten %S Sekunden" ); 
    MessageBox(erg,"Ergebnis");
    

    Schade nur, dass die Formatierung mit %02 für die Tage nicht geht.
    Alles andere wird immer mit einer führenden Null angezeigt, wenn es nicht
    zweistellig ist. Macht aber wohl auch sonst keinen Sinn, da die Tage ja
    u.U. auch 5, 6 oder sonstwas stellig sein können...


  • Mod

    1. Mit COleDateTime hättest Du das Sommerzeit-Problem nicht.
    Für mich ein Hauptgrund CTime zu meiden.
    Außerdem gibt es FormatGMT.
    2. Kannst Du ja die .Get... Funktionen verwenden und mit CString::Format formtieren wie Du willst, oder?



  • Hallo Martin.
    zu 2.: das habe ich probiert, aber er lässt mir die Werte auf 0, obwohl
    ts.GetSeconds() eindeutig einen Wert enthält, der, wenn ich ihn einzeln
    in einen CString formatiere, auch angezeigt wird.

    Kann ich evtl. nicht mehr als 3 Parameter für Format mitgeben?
    Lasse ich einen Wert weg (egal welchen), werden die anderen korrekt
    angezeigt 😕 Ich habe das projekt schon bereingt und neu erstellen
    lassen. Gleiches Ergebnis.

    COleDateTime schaue ich mir gleich an 👍


  • Mod

    Zeig mal Deinen Code.



  • Ist im Wesentlichen der Code von weiter oben:

    CTime t1( 1999, 3, 19, 22, 15, 00, 1 ); // 10:15PM March 19, 1999 
    CTime t2( 1999, 3, 20, 22, 15, 10, 1 ); // 10:15PM March 20, 1999 
    CTimeSpan ts = t2 - t1;  // Subtract 2 CTimes 
    
    	CString zeitspanne; 
    	zeitspanne.Format("%2d Tage %2d Stunden %2d Minuten %2d Sekunden",ts.GetDays(),ts.GetHours(),ts.GetMinutes(),ts.GetSeconds()); 
    	MessageBox(zeitspanne,"Ergebnis");
    

    Es wird 1 Tag ausgewiesen und der Rest überall mit 0 angegeben, obwohl hier
    noch 10 Sekunden auszugeben wären.



  • Ich habe es mal mit COleDateTime versucht und es funktioniert wunderbar!
    Jetzt bin ich noch nicht schlau daraus geworden welche gültigen Kombis
    es für das Datum gibt.

    Die MSDN sagt dazu dass z.B. folgendes zulässig ist:

    "25 January 1996"

    "8:30:00"

    "20:30:00"

    "January 25, 1996 8:30:00"

    "8:30:00 Jan. 25, 1996"

    "1/25/1996 8:30:00" // always specify the full year,

    // even in a 'short date' format

    Hier mein Versuch, der das Datum so angibt 31.10.2009 bis 15.11.2009.
    Auch das geht. Aber warum ist das so? Wie funktioniert die Logik dahinter?
    Woher kann die Anwendung wissen, wo der Tag und wo der Monat steht?
    Ich erhalte das jeweilige Datum aus CStrings:

    COleDateTime ersteUhr,zweiteUhr; 
    	COleDateTimeSpan diff;
    
    	CString dt = "10.10.2009 15:30:00"; 
    	ersteUhr.ParseDateTime(dt); 
    
    	CString dt2 = "31.10.2009 19:32:10"; 
    	zweiteUhr.ParseDateTime(dt2); 
    
    	diff= zweiteUhr - ersteUhr;                       
    
    CString uhrdiff;
    	uhrdiff=diff.Format("%D-%H:%M:%S"); 
    	MessageBox(uhrdiff);
    

    Ergebnis: 21 Tage 04 Stunden 02 Minuten und 10 Sekunden.
    Vielleicht kannst du mir noch verraten, wie ich so formatiere, dass ich
    statt der Tage, diese in die Stunden mit rein bekomme um das Format HH::MM::SS
    zu erhalten?


  • Mod

    Shoggy schrieb:

    Ist im Wesentlichen der Code von weiter oben:

    CTime t1( 1999, 3, 19, 22, 15, 00, 1 ); // 10:15PM March 19, 1999 
    CTime t2( 1999, 3, 20, 22, 15, 10, 1 ); // 10:15PM March 20, 1999 
    CTimeSpan ts = t2 - t1;  // Subtract 2 CTimes 
    
    	CString zeitspanne; 
    	zeitspanne.Format("%2d Tage %2d Stunden %2d Minuten %2d Sekunden",ts.GetDays(),ts.GetHours(),ts.GetMinutes(),ts.GetSeconds()); 
    	MessageBox(zeitspanne,"Ergebnis");
    

    Es wird 1 Tag ausgewiesen und der Rest überall mit 0 angegeben, obwohl hier
    noch 10 Sekunden auszugeben wären.

    Würdest Du einfach mal die Doku lesen!
    GetDays liefert einen LONGLONG ⚠ ⚠ ⚠

    Muss also heißen:

    zeitspanne.Format("%2lld Tage %2d Stunden %2d Minuten %2d Sekunden",ts.GetDays(),ts.GetHours(),ts.GetMinutes(),ts.GetSeconds());
    

  • Mod

    Shoggy schrieb:

    Hier mein Versuch, der das Datum so angibt 31.10.2009 bis 15.11.2009.
    Auch das geht. Aber warum ist das so? Wie funktioniert die Logik dahinter?
    Woher kann die Anwendung wissen, wo der Tag und wo der Monat steht?

    Es werden die Systemeinstellungen verwendet und ansonsten intelligent geparsed 😉



  • Ach mist, du hast natürlich Recht 😃

    LONGLONG totsec = ts.GetTotalSeconds(); 
    LONGLONG days=ts.GetDays();
    

    Bei der Formatierungsgeschichte (Tage zu Stunden) in Bezug auf
    COleDateTimeSpan muss ich dann wohl folgendes machen:

    cs_wert.Format("%g",diff.GetTotalHours());


  • Mod

    Shoggy schrieb:

    cs_wert.Format("%g",diff.GetTotalHours());

    Nö:

    cs_wert.Format("%d",static_cast<LONG>(diff.GetTotalHours()));
    

    Wenn Du wißt, dass die Different <0x7fffffff ist, dann geht auch ein einfacher cast.


Log in to reply