Solved

Checking the difference between 2 formatted dates

Posted on 2004-04-02
11
306 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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 Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

740 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