Solved

Checking the difference between 2 formatted dates

Posted on 2004-04-02
11
295 Views
Last Modified: 2010-04-05
This question builds from a previous question I ask/answered myself which had to do with a scheduling component but anyway the question is.

I have a form that has on it.

1 Timer (Timer1)
2 Labels (Label1 and Label2)

Every second Timer1 updates Label1 with the current date/time in this format  "4/22/04 @ 9:38:21 PM" minus the quotes ofcourse and on Label2 I have a static date/time in the same format as above but since it's not attached to the Timer it does not change (hence the word static)

Anyway how can I check to see if the time on Label2 is 5 minutes or more behind the time on Label1 (taking into account the @ symbol )

Thx,
Blue220
0
Comment
Question by:blue220
  • 5
  • 3
  • 2
  • +1
11 Comments
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10746148


procedure TForm1.Button1Click(Sender: TObject);
var
 P: Integer;
 T1: TDateTime;
 T2: TDateTime;
 AMins: Real;
begin
  P:= Pos('@',Label1.Caption) + 1;
  T1:= StrToDateTime(Copy(Label1.Caption,P, Length(Label1.Caption)));
  P:= Pos('@',Label2.Caption) + 1;
  T2:= StrToDateTime(Copy(Label2.Caption,P, Length(Label2.Caption)));
 AMins := (T2 - T1)*24*60;
 if AMins <= 5.00 then
  ShowMessage('It is 5 minutes or more behind!');
end;




Here it is again, with a comment for each line of code


procedure TForm1.Button1Click(Sender: TObject);
var
 P1: Integer;
 T1: TDateTime;
 P2: Integer;
 T2: TDateTime;
 AMins: Real;
begin
 //label1
 // get position of '@' character
 P1:= Pos('@',Label1.Caption) + 1;
 //extract the time portion after the '@' character
 T1:= StrToDateTime(Copy(Label1.Caption,P1, Length(Label1.Caption)));
 //label2
 // get position of '@' character
 P2:= Pos('@',Label2.Caption) + 1;
 //extract the time portion after the '@' character
 T2:= StrToDateTime(Copy(Label2.Caption,P2, Length(Label2.Caption)));
 //Get time difference in days * multiply against 24*60 for minutes
 AMins := (T2 - T1)*24*60;
 //display the difference in minutes
 ShowMessage(FormatFloat('0.00',AMins));
 if AMins <= 5.00 then
  ShowMessage('It is 5 minutes or more behind!');
end;

Shane
0
 

Author Comment

by:blue220
ID: 10746473
Thx for the reply but your solution does not take account the Date part of the caption so it would say it's 5 mins or more behind even if the date was set for 4/3/2050 which if I am not mistaken has not come up yet.
0
 
LVL 17

Expert Comment

by:mokule
ID: 10746936
Try this. Some corrections to Shanes code

procedure TForm1.Button1Click(Sender: TObject);
var
 P: Integer;
 T1: TDateTime;
 T2: TDateTime;
 AMins: Real;
// ASecs: Real;
 str: string;
begin
  str := DateTimeToStr(Now);
  Label1.Caption := str;

  str := Label1.Caption;
  P:= Pos('@',str);
  if P > 0 then
    Delete(str,P,2);
  T1:= StrToDateTime(str);

  str := Label2.Caption;
  P:= Pos('@',str);
  if P > 0 then
    Delete(str,P,2);
  T2:= StrToDateTime(str);
 AMins := (T1 - T2)*24*60;
// ASecs := (T1 - T2)*24*60*60;
 if AMins >= 5.00 then                        
  ShowMessage('It is 5 minutes or more behind!');
// if ASecs >= 5.00 then
//  ShowMessage('It is 5 seconds or more behind!');
end;
0
 
LVL 10

Expert Comment

by:Jacco
ID: 10746956
In the VCL DateUtils.pas there is a nice function

function MinutesBetween(const ANow, AThen: TDateTime): Int64;

The DateFormat is a different problem: "4/22/04 @ 9:38:21 PM"

function FunnyStrToDate(aDateTime: string): TDateTime;

  function StripInt(var aText: string): Integer;
  var
    Pos: Integer;
  begin
    Result := -1;
    while (Length(aText) > 1) and not (aText[1] in ['0'..'9']) do
      Delete(aText, 1, 1);
    if Length(aText) > 0 then
    begin
      Pos := 1;
      while (Pos <= Length(aText)) and (aText[Pos] in ['0'..'9']) do
        Inc(Pos);
      Result := StrToInt(Copy(aText, 1, Pos - 1));
      Delete(aText, 1, Pos);
    end;
  end;

var
  Month, Day, Year, Hour, Minute, Second: Integer;
begin
  // Funny-format 4/22/04 @ 9:38:21 PM
  Month  := StripInt(aDateTime);
  Day    := StripInt(aDateTime);
  Year   := StripInt(aDateTime);
  Hour   := StripInt(aDateTime);
  Minute := StripInt(aDateTime);
  Second := StripInt(aDateTime);
  // correct year (1980 - 2079 supported)
  if Year < 80 then
    Inc(Year, 2000)
  else
    Inc(Year, 1900);
  // correct hour (AM/PM)
  aDateTime := Trim(aDateTime);
  if Length(aDateTime) > 1 then
    if UpperCase(aDateTime[1]) = 'P' then
      Hour := Hour + 12;
  // encode the date
  if (Year <> -1) and (Month <> -1) and (Day <> -1) and (Hour <> -1) and (Minute <> -1) and (Second <> -1) then
    Result := EncodeDate(Year, Month, Day) + EncodeTime(Hour, Minute, Second, 0)
  else
    raise Exception.Create('Illegal funny date format');
end;

The timer function could then read:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := UpperCase(FormatDateTime('m"/"d"/"yy @ h:nn:ss am/pm', Now));
  if (FunnyStrToDate(Label1.Caption) - FunnyStrToDate(Label2.Caption)) * MinsPerDay > 5 then
    Label3.Caption := 'More then 5 behind!'
  else
    Label3.Caption := '...';
end;

Regards Jacco

P.S You need DateUtils in the uses


0
 

Author Comment

by:blue220
ID: 10749478
Thanks guys for you help but still having problems. Couple things I should mention is I am no longer using a label to store the "Static" Date/Time values on but rather a StringGrid (one date/time value per row)

Here is the code I am using to add the values to the grid.

procedure TForm1.Button1Click(Sender: TObject);
Var
  RWC : integer;
begin
  RWC := GridView1.RowCount;
  Gridview1.AddRow(1);
  GridView1.Cells[0, RWC] := Edit1.Text;
  GridView1.Cells[1, RWC] := DateToStr(DateTimePicker1.Date)+ ' @ ' + TimeToStr(DateTimePicker2.Time);

As you can see the "Static" Date/Time Values come from 2 DateTimePickers with the @ symbol in between them.

Also it might be helpful to know the code I am using to add the current time to Label1 and also check to see if one of the values in the StringGrid matches the value on the Label1 so here is that code and prehaps it would be better to just build off  of it.

procedure TForm1.Timer1Timer(Sender: TObject);
Var
 I : Integer;
begin
 Label1.Caption := (DateToStr(Date)+ ' @ ' + TimeToStr(Time));
 For I := 0 to GridView1.RowCount - 1 do
  if GridView1.Cells[1,I] = Label1.Caption then
   ShowMessage('Match Found');
end;


I have upped the points for this question to 200 to make it worth your time.

Thx Again,
Blue220
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 17

Expert Comment

by:mokule
ID: 10749638
What do You expect now?
This code checks for time in Label2 is 5 min "bigger" than time in grid row I.

procedure TForm1.Button1Click(Sender: TObject);
var
 P: Integer;
 T1: TDateTime;
 T2: TDateTime;
 AMins: Real;
 str: string;
begin
  str := Label1.Caption;
  P:= Pos('@',str);
  if P > 0 then
    Delete(str,P,2);
  T1:= StrToDateTime(str);

  str := GridView1.Cells[1,I];
  P:= Pos('@',str);
  if P > 0 then
    Delete(str,P,2);
  T2:= StrToDateTime(str);
 AMins := (T1 - T2)*24*60;
 if AMins >= 5.00 then                        
  ShowMessage(' GridView1 is 5 minutes or more behind Label1');
end;

0
 

Author Comment

by:blue220
ID: 10749911
Haven't tested the code but from what I can see it would only test for 1 cell in the Grid and I have many cells in the grid so that will not work.

Sorry you did not understand the code provided above but it was important to show you the changes I made to the program so we did not go round and round all day long with code that would not fit my needs....


Basically what I am doing is this...

Each time I press a Button the values I set in the DateTimePickers are added to one row on the Grid in the format "3/4/2004 @ 7:19:27 PM"  

Now on the timer I check every second ALL the rows in the Grid to see if one of those dates/times match the current date/time on the label and if so show the message "Match Found"

Now all I'm trying to do is the same thing as above with the checking and stuff but if it finds a date/time that is 5 mins or more behind the current date/time then show the message "5 mins or more behind current time" and it should be in the same for loop that I am using to check for a "matched" date/time.

With me so far... I hope so...


Anyway here again is the code I am using to check for a "matched" date/time.

procedure TForm1.Timer1Timer(Sender: TObject);
Var
   I : Integer;
begin
    Label1.Caption := (DateToStr(Date)+ ' @ ' + TimeToStr(Time));
    For I := 0 to GridView1.RowCount - 1 do
    if GridView1.Cells[1,I] = Label1.Caption then
       ShowMessage('Match Found');
end;

Like I said all that needs to be done is in the above For Loop add the code to check if one of the date/time values in the Grid is 5 mins or more behind the current date and time and if so then show the message "5 mins or more behind current time"

Hope that makes things clearer.
0
 
LVL 17

Accepted Solution

by:
mokule earned 200 total points
ID: 10749945
I've just assumed that You alone do some copy/paste operations, because I wasn't sure about Your intensins.
Here it is the code.


procedure TForm1.Timer1Timer(Sender: TObject);
Var
   I : Integer;
 P: Integer;
 T1: TDateTime;
 T2: TDateTime;
 AMins: Real;
 str: string;
begin
    Label1.Caption := (DateToStr(Date)+ ' @ ' + TimeToStr(Time));
    For I := 0 to GridView1.RowCount - 1 do
    if GridView1.Cells[1,I] = Label1.Caption then
       ShowMessage('Match Found');
    else
      begin
      str := Label1.Caption;
      P:= Pos('@',str);
      if P > 0 then
         Delete(str,P,2);
      T1:= StrToDateTime(str);

      str := GridView1.Cells[1,I];
      P:= Pos('@',str);
      if P > 0 then
         Delete(str,P,2);
     T2:= StrToDateTime(str);
     AMins := (T1 - T2)*24*60;
     if AMins >= 5.00 then                        
        ShowMessage(' GridView1 is 5 minutes or more behind Label1');
      end;
end
0
 

Author Comment

by:blue220
ID: 10750170
Assuming your code takes into account the AM/PM part of the date/time it looks like it's working fine ... So thx for the help
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10750224
thats messed up - uses my code and i don't even get an assist?

Ahhh - rite

Shane
0
 

Author Comment

by:blue220
ID: 10750329
Sorry bout that .... I forgot it started out with your code ... I will open a new question and award you points as well...
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video discusses moving either the default database or any database to a new volume.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now