TDM Geschrieben 11. Januar 2007 Teilen Geschrieben 11. Januar 2007 Hallo, ich brauche Hilfe beider Verwendung von Objekten von CDateTimeCtrl und CTime: [Vorwor] Ich habe eine Dialogmaske mit 4 CDateTimeCtrl Steuerelementen; (Start-Datum, Start-Zeit, Ende-Datum, Ende-Zeit) Dafür musste ich folglich 4 CTime-Variablen deklarieren. (Oder geht das auch einfacherer, dass ich die Steuerung beider Objekte z.B. über eine Variable machen könnte?) Da dieses Dialogfenster 3 Mal auftritt (3 verschiedene Zeitspanntypen) hab ich mich der Generalisierung bedient: CZeit als abstrakte Basisklasse und die Unterklassen CBereitschaftszeit, CEinsatzzeit und CKorrektur. Damit ich die obengenannten 4 Zeitobjekte schön von jeweiligen Klasse abkapseln konnte, wurde dafür noch eine Struktur erstellt: typedef struct STime { ETime_t p_eeTimeType; CTime p_oeStartDate; CTime p_oeStartTime; CTime p_oeEndDate; CTime p_oeEndTime; } STime_t; Ein Objekt dieser Struktur findet sich in der Basisklasse. Der Konstruktor von CZeit ist wie folgt deklariert: CZeit::CZeit() { this -> p_bSetEndDate(CTime(p_oGetEndDate().GetYear(), p_oGetEndDate().GetMonth(), p_oGetEndDate().GetDay(), 0, 0, 0)); this -> p_bSetEndTime(CTime(1970, 1, 1, p_oGetEndTime().GetHour()+1, p_oGetEndTime().GetMinute(), 0)); this -> p_bSetStartDate(CTime(p_oGetStartDate().GetYear(), p_oGetStartDate().GetMonth(), p_oGetStartDate().GetDay(), 0, 0, 0)); this -> p_bSetStartTime(CTime(1970, 1, 1, p_oGetStartTime().GetHour()+1, p_oGetStartTime().GetMinute(), 0)); } Das setzen neuer CTime-Objekte ist wichtig, denn beim Erzeugen würden Restbestände z.B. von Sekunden vorhanden sein und den späteren Programmablauf verfälschen. [CZeit & GUI] Damit meine Dialoge auf die Sachen speichern, sind natürlich Gettings und Settings vorhanden. (bei den CZeit-Objekten, wie auch bei dem Dialog) Nach dem erzeugen eines Dialogs, wird die jeweilige CZeit-Instanz gesetzt: void CEinsatzzeitDlg:_setEinsatzzeit(const CEinsatzzeit& p_oEinsatzzeit) { if (&p_oEinsatzzeit != NULL) { this -> m_oeMember = p_oEinsatzzeit; m_updateFields(); } }[/code] Und danach die Oberfläche geupdated: [code]void CEinsatzzeitDlg::m_updateFields(void) { m_oeValEzStartTime =this -> m_oeMember.p_oGetStartTime(); m_oeValEzStartDate = this -> m_oeMember.p_oGetStartDate(); m_oeValEzEndTime = this -> m_oeMember.p_oGetEndTime(); m_oeValEzEndDate = this -> m_oeMember.p_oGetEndDate(); m_beValEzTrace = this -> m_oeMember.p_bGetTrace(); p_setRz(m_oeMember.p_bGetRZ()); UpdateData(false); } Nach einem Klick auf OK, wird die CZeit dann gespeichert: void CEinsatzzeitDlg::OnOK() { UpdateData(true); this -> m_oeMember.p_bSetStartTime(m_oeValEzStartTime); this -> m_oeMember.p_bSetStartDate(m_oeValEzStartDate); this -> m_oeMember.p_bSetEndTime(m_oeValEzEndTime); this -> m_oeMember.p_bSetEndDate(m_oeValEzEndDate); if (m_poParentFrame != NULL) { m_poParentFrame -> p_bSetEinsatzzeit(this -> m_oeMember); m_poParentFrame -> UpdateData(true); } CDialog::OnOK(); } Soweit zur Erklärung des Sachverhalts... [Problem] Wenn ich in der Dialogmaske eine Zeit (kein Datum) auf 00:xx setzen will, bekomme ich einen Assert: Timecore.cpp Line: 40 Das Hauptproblem scheint aber eher in mktime.c in _make_time_t(struct tm*, int) zu liegen - genauer bei: tmptm1 += _timezone. Ist es normal das _timezone -3600 ist ? Wäre dankbar für Hilfe. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 11. Januar 2007 Teilen Geschrieben 11. Januar 2007 Ist es normal das _timezone -3600 ist ?Die MSDN Library sagt: _timezone: Difference in seconds between coordinated universal time and local time. Das sollte also für Mitteleuropäische Zeit üblich sein. Dabei kommt dann wohl ein Datum heraus, das in CTime nicht mehr reinpasst, weil es vor dem 1.1.1970 liegt. Ich würde zu COleDateTime raten, da ist der Bereich deutlich größer. Außerdem brauchst du dich nicht mehr vor 2038 zu fürchten Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 12. Januar 2007 Autor Teilen Geschrieben 12. Januar 2007 Ok, ich hab COleDateTime probiert. Das Problem mit dem 00:xxer Datum ist nicht mehr da. Allerdings klappt die Ausgabe einfach nicht... Bsp: COleDateTimeSpan a_oTResult = (time_t) 0; ... //Calc gibt ein ulong zurück. //Nach aufruf ist m_span = 3600 (1h) a_oTResult += calc(); TRACE("RB:\t%s\n", a_oTResult.Format("%H:%M:%S")); //Ausgabe: //00:00:00 Wurde auch schon mit GetHours() etc. probiert. (Ich hasse Ole-Klassen und sie hassen mich. ) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 12. Januar 2007 Teilen Geschrieben 12. Januar 2007 //Nach aufruf ist m_span = 3600 (1h)Falsch. Du kannst zu einem COleDateTimeSpan nur andere COleDateTimeSpan mit += addieren. Hier wird also der Rückgabewert von calc implizit an den einzigen Konstruktor von COleDateTimeSpan, der genau einen Parameter (double) hat, übergeben. Dieser interpretiert den Wert aber als Tage, nicht als Sekunden. Du hast also 3600 Tage draufgerechnet. Das hat natürlich keinen Einfluss auf Stunden, Minuten oder Sekunden. Du musst explizit den anderen Konstruktor benutzen: a_oTResult += COleDateTimeSpan( 0, 0, 0, calc()); Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 16. Februar 2007 Autor Teilen Geschrieben 16. Februar 2007 Soweit geht alles - dennoch hätte ich eine andere Frage die hier reinpassen würde: Ich rufe COleDateTimeSpan::Format auf und lasse mir die Stunden bzw. Minuten ausgeben. Allerdings sind das immer nur die aktuellen Stunden und Minuten; sprich: Tage werden nicht umgewandelt. Bei einer Dauer von 1d:2h:30m werden z.b. nur 2h:30m angezeigt statt eigentlich 26h. Als Formatcode nehme ich %H (00 - 23) Gibt es einen Formatcode, der die absolute Stundenzahl ausgibt ? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 16. Februar 2007 Teilen Geschrieben 16. Februar 2007 Gibt es einen Formatcode, der die absolute Stundenzahl ausgibt ?Nein. Du kannst diesen Wert mit COleDateTimeSpan::GetTotalHours rausholen und dann selbst in einen String umwandeln. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 16. Februar 2007 Autor Teilen Geschrieben 16. Februar 2007 Gut, da ich keine Lust auf irgendwelche Formatierungsprobleme habe und das so und so in einen String lade: if (zeit.GetTotalHours() < 10.0f) text = zeit.Format("%H:%M"); else text.Format("%d:%s", (int) zeit.GetTotalHours(), zeit.Format("%M")); Wundertoll. Geht. Danke. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 16. Februar 2007 Teilen Geschrieben 16. Februar 2007 Wenn es dir nur um die führende Null geht, kannst du dir die Fallunterscheidung sparen, wenn du %02d als Format für die Stunden benutzt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.