blue220
asked on
Checking the difference between 2 formatted dates
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
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
ASKER
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.
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;
procedure TForm1.Button1Click(Sender
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;
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.Cap tion) - FunnyStrToDate(Label2.Capt ion)) * MinsPerDay > 5 then
Label3.Caption := 'More then 5 behind!'
else
Label3.Caption := '...';
end;
Regards Jacco
P.S You need DateUtils in the uses
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:
begin
Label1.Caption := UpperCase(FormatDateTime('
if (FunnyStrToDate(Label1.Cap
Label3.Caption := 'More then 5 behind!'
else
Label3.Caption := '...';
end;
Regards Jacco
P.S You need DateUtils in the uses
ASKER
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
Here is the code I am using to add the values to the grid.
procedure TForm1.Button1Click(Sender
Var
RWC : integer;
begin
RWC := GridView1.RowCount;
Gridview1.AddRow(1);
GridView1.Cells[0, RWC] := Edit1.Text;
GridView1.Cells[1, RWC] := DateToStr(DateTimePicker1.
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:
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
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;
This code checks for time in Label2 is 5 min "bigger" than time in grid row I.
procedure TForm1.Button1Click(Sender
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;
ASKER
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.
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:
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
thats messed up - uses my code and i don't even get an assist?
Ahhh - rite
Shane
Ahhh - rite
Shane
ASKER
Sorry bout that .... I forgot it started out with your code ... I will open a new question and award you points as well...
procedure TForm1.Button1Click(Sender
var
P: Integer;
T1: TDateTime;
T2: TDateTime;
AMins: Real;
begin
P:= Pos('@',Label1.Caption) + 1;
T1:= StrToDateTime(Copy(Label1.
P:= Pos('@',Label2.Caption) + 1;
T2:= StrToDateTime(Copy(Label2.
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
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.
//label2
// get position of '@' character
P2:= Pos('@',Label2.Caption) + 1;
//extract the time portion after the '@' character
T2:= StrToDateTime(Copy(Label2.
//Get time difference in days * multiply against 24*60 for minutes
AMins := (T2 - T1)*24*60;
//display the difference in minutes
ShowMessage(FormatFloat('0
if AMins <= 5.00 then
ShowMessage('It is 5 minutes or more behind!');
end;
Shane