Datum und Uhrzeit vergleichen geht nicht...



  • Hallo

    bekomme es nicht gelöst. das der BCB6 mir Datum+Zeit korrekt mit Operatoren vergleicht. Ich möchte ein Datum mit Uhrzeit innerhalb zweier Grenzen prüfen.

    AnsiString z1,zADate1,zADate2;
     TDateTime Date1,Date2,Date;                                                    // vorbereiten
    
     zADate1="10.05.2007 10:46:49";                                                 // Datum+Zeit Start
     zADate2="11.05.2007 18:20:31";                                                 // Datum+Zeit Ende
     z1     ="10.05.2007 09:30:18";                                                 // zu prüfendes Datum+Zeit
    
     Date1   =StrToDateTimeDef(zADate1+" "+zAUhr1,Now());                           // Datum+Uhr von
     Date2   =StrToDateTimeDef(zADate2+" "+zAUhr2,Now());                           // Datum+Uhr bis
    
     Date =StrToDateTimeDef(z1,Now());                                              // Datum+Uhrzeit vom Meldeeintrag
     if(PrgComp) { ShowMessage(DateTimeToStr(Date)+"\r\rMeldezeit z1: "+z1+"\r\rDatum von: "+DateTimeToStr(Date1)+"\rDatum bis: "+DateTimeToStr(Date2)); } // nur im IDE
     if(Date<Date1 || Date>Date2) { continue; }                                     // Zeit falsch
    
     // Datum+Zeit liegt im Bereich Date1 und Date 2...
    

    In diesem Beispiel müsste die Abfrage falsch sein, da Date ausserhalb Date1 liegt (mit der Uhrzeit älter). Das Datum wird korrekt geprüft, die Uhrzeit nicht. Er müsste aber doch als TDateTime alles prüfen, oder? Also Datum und Uhrzeit... 😕

    Danke für jeden Tip, sitze schon Stunden dran (natürlich könnte ich die Zeit rausfiltern und explizit für den Starttag und Endtag des vorgegebenen Zeitrahmens abprüfen, aber das halte ich für unsauber).

    Gruss Stefan



  • Hallo,

    "zADate1" und "zADate2" hat doch schon eine Uhrzeit... warum fügst Du dann noch eine Uhrzeit hinzu ("zAUhr1" bzw. "zAUhr2") ?

    Und wenn ich das richtig verstanden habe, willst Du prüfen, ob "Date" innerhalb von "Date1" und "Date2" liegt, oder ?
    Dann würde ich das so machen :

    if (Date > Date1 && Date < Date2)
    ...
    

    Nash



  • Hallo Nash,

    danke für Deine Antwort. Du hast natürlich Recht. Hatte den Quellecode übernommen und angepasst und die Uhrzeit vergessen zu löschen. Korrekt ist es natürlich so:

    AnsiString z1,zADate1,zADate2,zAUhr1,zAUhr2;
     TDateTime Date1,Date2,Date;                                                    // vorbereiten
    
     zADate1="10.05.2007"; zAUhr1="10:46:49";                                       // Datum+Zeit Start
     zADate2="11.05.2007"; zAUhr2="18:20:31";                                       // Datum+Zeit Ende
     z1     ="10.05.2007 09:30:18";                                                 // zu prüfendes Datum+Zeit
    
     Date1   =StrToDateTimeDef(zADate1+" "+zAUhr1,Now());                           // Datum+Uhr von
     Date2   =StrToDateTimeDef(zADate2+" "+zAUhr2,Now());                           // Datum+Uhr bis
    
     Date =StrToDateTimeDef(z1,Now());                                              // Datum+Uhrzeit vom Meldeeintrag
     if(PrgComp) { ShowMessage(DateTimeToStr(Date)+"\r\rMeldezeit z1: "+z1+"\r\rDatum von: "+DateTimeToStr(Date1)+"\rDatum bis: "+DateTimeToStr(Date2)); } // nur im IDE
     if(Date<Date1 || Date>Date2) { continue; }                                     // Zeit falsch
    
     // Datum+Zeit liegt im Bereich Date1 und Date 2...
    

    Dein Vorschlag

    if (Date > Date1 && Date < Date2)
    ...
    

    ändert ja nichts an der Tatsache, daß die Uhrzeit im Vergleich scheinbar
    ignoriert wird. Ich nutze den OR Vergleich wegen einer Schleife...

    Hat denn keiner eine Idee, woran das liegt oder ist es eventuell ein Bug? 😕

    Grüsse, Stefan



  • Hallo,

    so funktioniert es:

    if(CompareDate(Datum,Datum1)==LessThanValue)    { continue; }                 // aktuelles Datum ist kleiner Datum von
    if(CompareDate(Datum,Datum2)==GreaterThanValue) { continue; }                 // aktuelles Datum ist grösser Datum bis
    if(CompareDate(Datum,Datum1)==EqualsValue && CompareTime(Time,Time1)==LessThanValue)    { continue; }  // Uhrzeit am Startdatum ist kleiner
    if(CompareDate(Datum,Datum2)==EqualsValue && CompareTime(Time,Time2)==GreaterThanValue) { continue; }  // Uhrzeit am Enddatum   ist grösser
    

    Also im direkten Vergleich TDateTime mit Operatoren < > usw. keine Chance;
    Datum und Uhrzeit jeweils in TDate und TTime getrennt funktioniert.

    Gruss, Stefan



  • bei mir funktioniert der Vergleich auch mit < oder >, und zwar auf die Sekunde genau

    nochmal zum Verständnis:
    in deinem Beispiel ist Date (10.05.2007 09:30:18) früher also kleiner als Date1 (10.05.2007 10:46:49), was dazu führt, dass er die Schleife durch das continue nicht weiter abarbeitet, sondern zum nächsten Durchlauf springt
    sobald man die Zeit bei Date (also bei z1) auf 10:47:00 stellt, geht er nicht in die Abbruchbedingung rein und würde den darauffolgenden Quellcode bearbeiten

    da TDateTime ja intern als double behandelt wird und zudem die Operatoren dafür auch überladen sind, sollte und wird das korrekt überprüft

    wie übergibst du die Werte für Date/z1 an die Schleife? ich geh mal davon aus, dass du nicht immer das gleiche Datum überprüfst



  • also ich denke auch, daß ich einen blöden Denkfehler mache;
    kontrolliere aber die Zeit mit ShowMessage (PrgComp ist true,
    wenn der IDE läuft) immer nach und bekomme sie korrekt angezeigt,
    daher verstehe ich es nicht ganz.

    Aber hier mal mein aktueller Code (anstelle der Compare.. Zeilen hatte
    ich vorher die simple Zeile mit dem Vergleich if(Date<Date1 || Date>Date2) { continue; }

    try {                                                                          // Fehlerroutine Start
     Integer i2,iSymb,iAnz,iCol; AnsiString z1,z2,zAUhr1,zAUhr2,zAText; Boolean o1; // Vars definieren
     TListView   *LView1,*LView2;                                                   // vorbereiten
     TListItem   *LItem;                                                            // vorbereiten
     TDateTime Date1,Date2,Date;                                                    // vorbereiten
     TTime     Time1,Time2,Time;                                                    // vorbereiten
     TDate     Datum1,Datum2,Datum;                                                 // vorbereiten
    
     LView1=frm1_lv2_Meldungen;                                                     // ListView übergeben
     LView2=frm1_lv3_Auswertung;                                                    // ListView übergeben
     iAnz  =LView1->Items->Count;                                                   // Anzahl Einträge
     if(iAnz==0) {                                                                  // keine Meldungen
      ShowMessage("Es liegen zur Zeit keine Meldungen vor.\r\rEine Auswertung ist daher nicht möglich (siehe Reiter Alle Meldungen).");
      return;                                                                       // und raus
     }                                                                              // ende
    
     iAUhr1  =frm1_cb3_Uhr1->ItemIndex;                                             // Uhrzeit von merken
     iAUhr2  =frm1_cb3_Uhr2->ItemIndex;                                             // Uhrzeit bis merken
     iAText  =frm1_cb3_Meldetext->ItemIndex;                                        // Meldetext   merken
    
     zADate1 =frm1_ed3_Datum1->Text;                                                // Datum von
     zADate2 =frm1_ed3_Datum2->Text;                                                // Datum bis
     zAUhr1  =frm1_cb3_Uhr1->Text+":00";                                            // Uhrzeit von
     zAUhr2  =frm1_cb3_Uhr2->Text+":59";                                            // Uhrzeit bis
     zAText  =frm1_cb3_Meldetext->Text;                                             // Meldetext
     zAID    =frm1_ed3_MeldeID->Text;                                               // PersonenID
     zAPerson=frm1_cb3_Person->Text;                                                // Person
     zATel   =frm1_cb3_Telefon->Text;                                               // Telefon
     zAGeb   =frm1_cb3_Gebaeude->Text;                                              // Gebäude
     if(zAUhr1=="00:00:00") { zAUhr1="00:00:01"; }                                  // Start Mitternacht ggfs. korrigieren
    
     Date1   =StrToDateTimeDef(zADate1+" "+zAUhr1,Now());                           // Datum+Uhr von
     Date2   =StrToDateTimeDef(zADate2+" "+zAUhr2,Now());                           // Datum+Uhr bis
     Datum1  =StrToDateDef(zADate1,Now());                                          // nur Datum von
     Datum2  =StrToDateDef(zADate2,Now());                                          // nur Datum bis
     Time1   =StrToTimeDef(zAUhr1,Now());                                           // nur Uhrzeit von
     Time2   =StrToTimeDef(zAUhr2,Now());                                           // nur Uhrzeit bis
     if(PrgComp) { ShowMessage("Datum von - bis: "+DateToStr(Datum1)+" - "+DateToStr(Datum2)+"\r\rUhrzeit von - bis: "+TimeToStr(Time1)+" - "+TimeToStr(Time2)); } // nur im IDE
    
     i2=frm1_cb3_Person->Items->IndexOf(zAPerson);                                  // schon in Auswahlliste enthalten?
     if(i2==-1) {                                                                   // Nein
      if(frm1_cb3_Person->Items->Count>24) { frm1_cb3_Person->Items->Delete(24); }  // zuviele Einträge? Dann letzten Eintrag löschen
      frm1_cb3_Person->Items->Insert(0,zAPerson);                                   // und am Anfang einfügen
     }                                                                              // ende if(i2
     i2=frm1_cb3_Telefon->Items->IndexOf(zATel);                                    // schon in Auswahlliste enthalten?
     if(i2==-1) {                                                                   // Nein
      if(frm1_cb3_Telefon->Items->Count>24) { frm1_cb3_Telefon->Items->Delete(24); }// zuviele Einträge? Dann letzten Eintrag löschen
      frm1_cb3_Telefon->Items->Insert(0,zATel);                                     // und am Anfang einfügen
     }                                                                              // ende if(i2
     i2=frm1_cb3_Gebaeude->Items->IndexOf(zATel);                                   // schon in Auswahlliste enthalten?
     if(i2==-1) {                                                                   // Nein
      if(frm1_cb3_Gebaeude->Items->Count>24) { frm1_cb3_Gebaeude->Items->Delete(24); }// zuviele Einträge? Dann letzten Eintrag löschen
      frm1_cb3_Gebaeude->Items->Insert(0,zAGeb);                                    // und am Anfang einfügen
     }                                                                              // ende if(i2
    
     //frm1_lbl3_Auswertung->Caption=DateTimeToStr(Date1)+" - "+DateTimeToStr(Date2);// Abrechnungszeitraum schreiben
     frm1_lbl3_Auswertung->Caption=" Auswertezeitraum: "+FormatDateTime("dd.mm.yyyy, hh:mm:ss",Date1)+" - "+FormatDateTime("dd.mm.yyyy, hh:mm:ss",Date2);// Abrechnungszeitraum schreiben
     frm1_MenuAuswertungsichern->Enabled=false;                                     // Menü sperren
     LView2->Items->Clear();                                                        // Liste löschen
    
     Screen->Cursor=crHourGlass; Application->ProcessMessages();                    // Sanduhr
    
     frm1_proBalken->Max=iAnz;                                                      // Maxwert
     frm1_proBalken->Position=0;                                                    // Regler einstellen
    
     for(int i1=0;i1<iAnz;i1++) {                                                   // alle Einträge
      frm1_proBalken->Position=i1+1;                                                // Regler einstellen
      Application->ProcessMessages();                                               // events abarbeiten
    
      LItem=LView1->Items->Item[i1];                                                // Zeile übergeben
      z1   ="|"+LItem->Caption+"|";                                                 // 1. palte auslesen
      iCol =LItem->SubItems->Count;                                                 // Anzahl SubSpalten
      for(int i0=0;i0<iCol;i0++) {                                                  // alle Spalten
       z1=z1+LItem->SubItems->Strings[i0]+"|";                                      // auslesen und zusammensetzen
      }                                                                             // ende for(i0
    
      iSymb=LItem->ImageIndex;                                                      // LED Index auslesen
                                                                                    // PRÜFEN BEDINGUNGEN START
                                                                                    // ------------------------
      z2   =LItem->Caption; o1=false;                                               // tt.mm.jjjj, ss:mm:ss
      if(z2.Length()!=20 || z2.AnsiPos(".")==0 || z2.AnsiPos(":")==0) { o1=true; }  // Zeitangabe falsch
    
      Date =StrToDateTimeDef(z2,Now());                                             // Datum+Uhr vom Meldeeintrag
      Datum=StrToDateDef(z2.SubString( 1,10),Now());                                // Datum vom Meldeeintrag
      Time =StrToTimeDef(z2.SubString(13, 8),Now());                                // Uhrzeit vom Meldeeintrag
      //if(PrgComp) { ShowMessage(DateToStr(Datum)+"\r\rMeldezeit z2: "+z2+"\r\rDatum von: "+DateToStr(Datum1)+"\rDatum bis: "+DateToStr(Datum2)+"\r\rErgebniss:\r\rVergleich Datum von: "+BoolToStr(Datum<Datum1)+"\r\rCompare: "+IntToStr(CompareDate(Datum,Datum1))); } // nur im IDE
      //if(PrgComp) { ShowMessage(DateToStr(Datum)+"\r\rMeldezeit z2: "+z2+"\r\rDatum von: "+DateToStr(Datum1)+"\rDatum bis: "+DateToStr(Datum2)+"\r\rErgebniss:\r\rVergleich Datum von: "+BoolToStr(Datum<Datum1)+"\r\rCompare: "+IntToStr(CompareDate(Datum,Datum1))); } // nur im IDE
    
      if(CompareDate(Datum,Datum1)==LessThanValue)    { continue; }                 // aktuelles Datum ist kleiner Datum von
      if(CompareDate(Datum,Datum2)==GreaterThanValue) { continue; }                 // aktuelles Datum ist grösser Datum bis
      if(CompareDate(Datum,Datum1)==EqualsValue && CompareTime(Time,Time1)==LessThanValue)    { continue; }  // Uhrzeit am Startdatum ist kleiner
      if(CompareDate(Datum,Datum2)==EqualsValue && CompareTime(Time,Time2)==GreaterThanValue) { continue; }  // Uhrzeit am Enddatum   ist grösser
    
      if(iAText>0) {                                                                // Meldetext abfragen (0 = >Alle Meldetexte<)
       if(iAText==1 && iSymb!=18) { continue; }                                     // Meldetext Notruf    rt LED falsch
       if(iAText==2 && iSymb!=19) { continue; }                                     // Meldetext Vitalruf  ge LED falsch
       if(iAText==3 && iSymb!=26) { continue; }                                     // Meldetext ..vor Ort gn LED falsch
       if(iAText==4 && iSymb!=20) { continue; }                                     // Meldetext Unbekannt gr LED falsch
      }                                                                             // ------------------------
      if(zAID.Length()     >0 && z1.AnsiPos("|"+zAID)     ==0) { continue; }        // PersonenID falsch
      if(zAPerson.Length() >0 && z1.AnsiPos("|"+zAPerson) ==0) { continue; }        // Person     falsch
      if(zATel.Length()    >0 && z1.AnsiPos("|"+zATel)    ==0) { continue; }        // Telefon    falsch
      if(zAGeb.Length()    >0 && z1.AnsiPos("|"+zAGeb)    ==0) { continue; }        // Gebäude    falsch
                                                                                    // PRÜFEN BEDINGUNGEN ENDE
    
      LItem=LView2->Items->Add();                                                   // neue Zeile
      LItem->ImageIndex=iSymb;                                                      // und LED zuordnen
      LItem->StateIndex=abs(int(o1));
      LItem->Caption=DatenPipe(1,1,z1,"!!");                                        // und einsetzen
      for(int i0=0;i0<iCol;i0++) {                                                  // alle Subspalten
       LItem->SubItems->Add(DatenPipe(1,i0+2,z1,"!!"));                             // hinten anhängen
      }                                                                             // ende for(i0
    
     }                                                                              // ende for(i1
     frm1_proBalken->Position=0;                                                    // Regler einstellen
    
     iAnz=LView2->Items->Count;                                                     // Anzahl Einträge
     frm1_lbl3_Tab->Visible=iAnz>0;                                                 // Label zeigen/verbergen
     frm1_MenuAuswertungsichern->Enabled=iAnz>0;                                    // Menü sperren/freigeben
     frm1_lbl3_Ergebniss->Caption="Ergebnissliste ("+IntToStr(iAnz)+"):";           // Label aktualisieren
     frm1_stbStatus->Panels->Items[2]->Text="Ausw.: "+IntToStr(iAnz);               // Statusbar aktualisieren
    
     Screen->Cursor=crDefault;   Application->ProcessMessages();                    // Pfeil
    
     } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TForm1::frm1_btn3_AuswertenClick()", MB_OK); }  // Fehler anzeigen
    

    Interessiert mich natürlich sehr, wo der Hase begraben liegt 🙄

    Gruss und Danke für Tips, Stefan



  • in welcher Form stehen denn die Einträge in der ListBox drin?
    so wie hier beschrieben

    z2   =LItem->Caption; o1=false;   // [b]tt.mm.jjjj, ss:mm:ss[/b]
    

    oder ohne Komma?

    mit Komma würde immer Now() verwendet werden, da die Funktion StrToDateTimeDef nur Strings im Format "dd.mm.yyyy hh🇲🇲ss" verarbeiten kann



  • Hallo, Linnea

    ohne Komma 🙂 bzw. hatte es mit Komma und danach gleich ein Replace()
    gemacht und es gelöscht. Über das Komma war ich am Anfang gestolpert...

    Mich wundert halt, das mir die entsprechende Rückwandlung mit DateToStr,
    DateTimeToStr usw. z.B. beim ShowMessage die Daten absolut korrekt darstellt.

    Mir ist übrigens aufgefallen, daß beim jetzigen Programmbeispiel der
    Vergleich

    if(Date<Date1 || Date>Date2) { continue; }
    

    das Datum korrekt prüft; die Uhrzeit aber ignoriert. Vielleicht hilft
    das weiter... grübel..


Anmelden zum Antworten