Discussion:
Two apparently equal dates give greater than as true
(too old to reply)
John Austin
2006-09-04 10:43:01 UTC
Permalink
In my VB6 app,I get occasional problems where two date variables show the
same date and time, show the same Cdbl() values and yet go through Greater
Than logic in the program. Whilst this is probably due to floating point
issues it is a big problem in my app. For example, this is from the debug
window:

? Dg.ToTime > Eg.SignOff;Dg.ToTime ; Eg.SignOff; cdbl(Dg.ToTime);cdbl(
Eg.SignOff )
True 04/09/2006 17:13:00 04/09/2006 17:13:00 38964.7173611111
38964.7173611111

I really need an efficient work around to this problem!

Thanks
--
John Austin
Bob Butler
2006-09-04 13:25:34 UTC
Permalink
Post by John Austin
In my VB6 app,I get occasional problems where two date variables show
the same date and time, show the same Cdbl() values and yet go
through Greater Than logic in the program. Whilst this is probably
due to floating point issues it is a big problem in my app. For
? Dg.ToTime > Eg.SignOff;Dg.ToTime ; Eg.SignOff; cdbl(Dg.ToTime);cdbl(
Eg.SignOff )
True 04/09/2006 17:13:00 04/09/2006 17:13:00 38964.7173611111
38964.7173611111
I really need an efficient work around to this problem!
What do you get for DateDiff("s",Dg.ToTime,Eg.SignOff) ?
--
Reply to the group so all can participate
VB.Net: "Fool me once..."
John Austin
2006-09-04 14:05:01 UTC
Permalink
Hi Bob, DateDiff("s",A,B)= zero seconds, but A-B = 7.27595761418343E-12
(about 0.6 microseconds).

This project has hundreds of date/time comparisons in but I only get this
problem every few weeks. As most of the dates are in classes, I have added
methods called IsEqualTo, IsGreaterThan and IsLessThan that use
DateDiff("s",... to establish the equality etc, but it would take days to
replace all of the comparisons.
--
John Austin
Post by Bob Butler
Post by John Austin
In my VB6 app,I get occasional problems where two date variables show
the same date and time, show the same Cdbl() values and yet go
through Greater Than logic in the program. Whilst this is probably
due to floating point issues it is a big problem in my app. For
? Dg.ToTime > Eg.SignOff;Dg.ToTime ; Eg.SignOff; cdbl(Dg.ToTime);cdbl(
Eg.SignOff )
True 04/09/2006 17:13:00 04/09/2006 17:13:00 38964.7173611111
38964.7173611111
I really need an efficient work around to this problem!
What do you get for DateDiff("s",Dg.ToTime,Eg.SignOff) ?
--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Michael C
2006-09-04 22:25:00 UTC
Permalink
Post by John Austin
Hi Bob, DateDiff("s",A,B)= zero seconds, but A-B = 7.27595761418343E-12
(about 0.6 microseconds).
This project has hundreds of date/time comparisons in but I only get this
problem every few weeks. As most of the dates are in classes, I have added
methods called IsEqualTo, IsGreaterThan and IsLessThan that use
DateDiff("s",... to establish the equality etc, but it would take days to
replace all of the comparisons.
Have you ever tried this sort of thing in an app? You'll probably find it's
complete within 10 to 15 minutes. It might be a bit more difficult if you
don't have a good method of finding the comparisons but still I doubt it
would take days.

Michael
John Austin
2006-09-04 14:38:02 UTC
Permalink
I have isolated the bug now. Of the two identical times, one was intput from
a text box, the other a result of a DateAdd call.
The bug can be demonstrated in the debug window:

?cdate("2006-09-04 17:13") - dateadd("n",600,cdate("2006-09-04 07:13"))
7.27595761418343E-12

?cdate("2006-09-04 17:13") > dateadd("n",600,cdate("2006-09-04 07:13"))
True

So adding 600 minutes to 07:13 is not the same as 17:13 - YUK!!
--
John Austin
Post by Bob Butler
Post by John Austin
In my VB6 app,I get occasional problems where two date variables show
the same date and time, show the same Cdbl() values and yet go
through Greater Than logic in the program. Whilst this is probably
due to floating point issues it is a big problem in my app. For
? Dg.ToTime > Eg.SignOff;Dg.ToTime ; Eg.SignOff; cdbl(Dg.ToTime);cdbl(
Eg.SignOff )
True 04/09/2006 17:13:00 04/09/2006 17:13:00 38964.7173611111
38964.7173611111
I really need an efficient work around to this problem!
What do you get for DateDiff("s",Dg.ToTime,Eg.SignOff) ?
--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Bob Butler
2006-09-04 15:11:20 UTC
Permalink
Post by John Austin
I have isolated the bug now. Of the two identical times, one was
intput from a text box, the other a result of a DateAdd call.
?cdate("2006-09-04 17:13") - dateadd("n",600,cdate("2006-09-04
07:13")) 7.27595761418343E-12
?cdate("2006-09-04 17:13") > dateadd("n",600,cdate("2006-09-04
07:13")) True
So adding 600 minutes to 07:13 is not the same as 17:13 - YUK!!
Since it's stored in floating point this is a not-so-unexpected side effect.
You may be able to clean up the value by passing it through the date
functions

d1=dateserial(2006,9,4)+timeserial(7,13,0)
d2=dateserial(2006,9,4)+timeserial(17,13,0)
d3=dateadd("n",600,d1)
?d2>d3
True
d3=dateserial(year(d3),month(d3),day(d3))+timeserial(hour(d3),minute(d3),sec
ond(d3))
?d2>d3
False
--
Reply to the group so all can participate
VB.Net: "Fool me once..."
John Austin
2006-09-04 15:38:01 UTC
Permalink
I have currently used the hideous Cdate(Cstr(DateAdd("m",...
which guarantees to give the same result as a time entered in a text box,
but I dont like it!

Interestingly, D2 = CDate("2006-09-04 07:13") + TimeSerial(600 \ 60, 600 Mod
60, 0) gives the same result as the DateAdd("n",600... function.
--
John Austin
Post by Bob Butler
Post by John Austin
I have isolated the bug now. Of the two identical times, one was
intput from a text box, the other a result of a DateAdd call.
?cdate("2006-09-04 17:13") - dateadd("n",600,cdate("2006-09-04
07:13")) 7.27595761418343E-12
?cdate("2006-09-04 17:13") > dateadd("n",600,cdate("2006-09-04
07:13")) True
So adding 600 minutes to 07:13 is not the same as 17:13 - YUK!!
Since it's stored in floating point this is a not-so-unexpected side effect.
You may be able to clean up the value by passing it through the date
functions
d1=dateserial(2006,9,4)+timeserial(7,13,0)
d2=dateserial(2006,9,4)+timeserial(17,13,0)
d3=dateadd("n",600,d1)
?d2>d3
True
d3=dateserial(year(d3),month(d3),day(d3))+timeserial(hour(d3),minute(d3),sec
ond(d3))
?d2>d3
False
--
Reply to the group so all can participate
VB.Net: "Fool me once..."
"Peter Huang" [MSFT]
2006-09-05 09:38:45 UTC
Permalink
Hi John,

Based on my research, we can consider the date type is a double type in
memory. So the arithmetic between double as a float arithmetic may have
error.
So when we programming against float data, we need to pay attention to the
error.

From the scenario the error 7.27595761418343E-12 is acceptable.
Commonly we did not compare two float type directly when they are very
close, e.g. the error is 7.27595761418343E-12.
We consider the two float is equal only when the error is less than certian
const number.

So for your scenario, I think one approach is to use DateDiff, also your
workaround is also OK.
Or you may try the float version compare.
e.g. when the |d1-d2| < 7.27595761418343E-10, we consider it is equal, this
depends on your concrete program requirement.
Commonly the requirement in Scientific Computing may be high, but I think
in the commonly usage, the error 7.27595761418343E-12 is not a problem.

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Ken Halter
2006-09-05 18:18:31 UTC
Permalink
Post by John Austin
I have currently used the hideous Cdate(Cstr(DateAdd("m",...
which guarantees to give the same result as a time entered in a text box,
but I dont like it!
Interestingly, D2 = CDate("2006-09-04 07:13") + TimeSerial(600 \ 60, 600 Mod
60, 0) gives the same result as the DateAdd("n",600... function.
--
John Austin
You might have some luck using, basically, a replacement for the "equals
sign" in this and any other floating point math problem you have in the
future (no matter what language you're coding in at the time). Here's a post
that contains a few links and a brief explaination of EPSILON.

Weird floating point problem
http://groups.google.com.my/group/microsoft.public.vb.general.discussion/msg/74b7abbe3645bd1b?hl=en&
--
Ken Halter - MS-MVP-VB - Please keep all discussions in the groups..
In Loving Memory - http://www.vbsight.com/Remembrance.htm
Loading...