Solved

Checking the difference between 2 formatted dates

Posted on 2004-04-02
11
310 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: 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

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!

Question has a verified solution.

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

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…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

739 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