TDM Geschrieben 11. Januar 2007 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.
Klotzkopp Geschrieben 11. Januar 2007 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
TDM Geschrieben 12. Januar 2007 Autor 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. )
Klotzkopp Geschrieben 12. Januar 2007 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());
TDM Geschrieben 16. Februar 2007 Autor 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 ?
Klotzkopp Geschrieben 16. Februar 2007 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.
TDM Geschrieben 16. Februar 2007 Autor 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.
Klotzkopp Geschrieben 16. Februar 2007 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.
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren
Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde Dich hier an.
Jetzt anmelden