habe einen Tag zuviel! woher???
-
int CHLRUSLG_SampleDlg::Datum(CString datum) { CTime t1(1999,1,1,0,0,0); CTime tc = CTime::GetCurrentTime(); CTime t0(2037,10,26,0,0,0); int day, month, year, tage; CString str_day, str_month, str_year, ch; int i =0; int j =0; //Eingabe des Datums im deutschen Standard-Format und berechnen der Tage // seit dem 01.01.1999 if ((datum!="") && (datum!="0")) { for (i; i<datum.GetLength(); i++) { ch = datum.GetAt(i); while((ch!=46) && (ch!="") && (ch!=47) && (ch!=45)) { if (ch!=46) { switch(j) { case 0: str_day+=ch; break; case 1: str_month+=ch; break; case 2: str_year+=ch; break; } } i++; if (i<datum.GetLength()) ch = datum.GetAt(i); else ch = "."; } j++; } day = atoi(str_day); month = atoi(str_month); year = atoi(str_year); if (year>=tc.GetYear()) { //die Klasse CTime lässt ein Datum höher dem 31.12.2037 nicht zu. Die // Eingabe eines solchen Datums würde zum Programmabsturz führen, was // dadurch verhindert wird, dass in einem solchen Fall t2=31.12.2037 // gesetzt wird if ((day>31)||(month>12)||(year>2037)) { day = 31; month = 12; year = 2037; } CTime t2(year, month, day,0,0,0); //Datum früher dem aktuellen Datum wird nicht akzeptiert if (t2>tc) { CTimeSpan ts = t2 - t1; tage = ts.GetDays(); } else { return -2; } } else { return -2; } } else { //sollte kein datum oder 0 eingegeben werden, wird tage = 0 // gesetzt und somit die Liezenz auf unendlich gesetzt return 0; } if (t1<t0) tage+=1; return tage; } void CHLRUSLG_SampleDlg::OnSelChange() { this->UpdateData(true); mv_sexp=slotList[(mv_snum+((mv_snum-1)*2)-1)]; mv_sdate=SDate(mv_sexp); mv_sval=slotList[(mv_snum+((mv_snum-1)*2))]; mv_ssng=slotList[(mv_snum+((mv_snum-1)*2)+1)]; this->UpdateData(false); }Mit diesem Code berechne ich die Anzahl der Tage vom 1.1.1999 bis zu meinem eingegebenen Datum. Läuft soweit auch reibungslos. Nur, wenn ich dann später wieder alles umrechne, um mein eingegebenes Datum wieder zu erhalten, habe ich manchmal einen Tag zuviel. Aber das auch nicht immer. Mal passts, mal nicht und ich weiß nicht woher.
Das zurückrechnen geschieht wie folgt:CString CHLRUSLG_SampleDlg::SDate(int iDate) { CTime t1(1999,1,1,0,0,0); CTimeSpan ts1(iDate,0,0,0); int day, month, year; CString datum; if (iDate==0) return "0"; if (iDate>=14179) iDate--; t1+=ts1; day = t1.GetDay(); month = t1.GetMonth(); year = t1.GetYear(); datum.Format("%d.%d.%d",day,month,year); return datum; }Kann mir jemand verraten, woran es liegt, bzw. wie ich es nun endgültig verhinder kann???
Danke
Teddy
[ Dieser Beitrag wurde am 08.05.2003 um 15:43 Uhr von Teddy editiert. ]
-
CTimeSpan
-
ja, benutz ich doch
-
So Leute, ich hab den Fehler, bzw. die schwäche von CTime / CTimeSpan entdeckt. Beide sind sehr ungenau und deshalb sollte man auf die Funktionen COleDateTime und COleDateTimeSpan zurückgreifen. Hier geht nix verloren.
Der Code sieht nun wie folgt aus:
int CHLRUSLG_SampleDlg::Datum(CString datum) { COleDateTime t1(1999,1,1,0,0,0); COleDateTime tc = COleDateTime::GetCurrentTime(); COleDateTime t0(2037,10,26,0,0,0); int day, month, year, tage; CString str_day, str_month, str_year, ch; int i =0; int j =0; //Eingabe des Datums im deutschen Standard-Format und berechnen der Tage // seit dem 01.01.1999 if ((datum!="") && (datum!="0")) { for (i; i<datum.GetLength(); i++) { ch = datum.GetAt(i); while((ch!=46) && (ch!="") && (ch!=47) && (ch!=45)) { if (ch!=46) { switch(j) { case 0: str_day+=ch; break; case 1: str_month+=ch; break; case 2: str_year+=ch; break; } } i++; if (i<datum.GetLength()) ch = datum.GetAt(i); else ch = "."; } j++; } day = atoi(str_day); month = atoi(str_month); year = atoi(str_year); if (year>=tc.GetYear()) { //die Klasse COleDateTime lässt ein Datum höher dem 31.12.9999 nicht zu. Die // Eingabe eines solchen Datums würde zum Programmabsturz führen, was // dadurch verhindert wird, dass in einem solchen Fall t2=31.12.9999 // gesetzt wird if ((day>31)||(month>12)||(year>2037)) { day = 31; month = 12; year = 9999; } COleDateTime t2(year, month, day,0,0,0); //Datum früher dem aktuellen Datum wird nicht akzeptiert if (t2>tc) { COleDateTimeSpan ts = t2 - t1; tage = (int)ts.GetDays(); } else { return -2; } } else { return -2; } } else { //sollte kein datum oder 0 eingegeben werden, wird tage = 0 // gesetzt und somit die Liezenz auf unendlich gesetzt return 0; } return tage; }Die Rückrechnung schaut nun so aus:
CString CHLRUSLG_SampleDlg::SDate(int iDate) { COleDateTime t1(1999,1,1,0,0,0); COleDateTimeSpan ts1(iDate,0,0,0); int day, month, year; CString datum; if (iDate==0) return "0"; if (iDate>=14179) iDate--; t1+=ts1; day = t1.GetDay(); month = t1.GetMonth(); year = t1.GetYear(); datum.Format("%d.%d.%d",day,month,year); return datum; }Das wär doch was für die FAQ, oder?
Teddy
-
Also ich konvertiere ein Datum aus einem String immer so:
CString datum = "01.02.2008"; int year, month, day; _stscanf( datum, _T("%2d.%2d.%4d"), &day, &month, &year);
-
Damit legst du aber eine Datumskonvention (z.B. dd.mm.yyyy) zugrunde und andere Formate wie z.b. dd-mm-yyyy fängst du damit nicht ab bzw. was machst du, wenn der User nicht 01.01.2004 eingibt, sondern 1.1.2004? Da ist es schon besser einfach die länge des Strings zu bestimmen und die entsprechenden Trennzeichen abzufragen, wie ich es mach.
Okay, geht bestimmt auch, aber wenn ich mir sowas ausdenke, wirds meistens komplizierter als mans brauch *grins*. Deshalb bin ich immer für alle Vorschläge offen.