Status: Accepted
Owner: [hidden email] Labels: Type-Defect Priority-Medium GLASS-Server Version-1.0-beta.8.6 New issue 254 by [hidden email]: DateAndTimes don't compare correctly http://code.google.com/p/glassdb/issues/detail?id=254 for discussion see: http://forum.world.st/DateAndTime-problem-td3394257.html the basic example is: With the following change to DataAndTime: DateAndTime class>>secondsSince2001 "^DateTime now asSecondsGmt - 3155760000." ^ (System _timeGmtFloat - 978307200) asScaledDecimal: 3. the following doesn't behave as expected: | date date2 | date := DateAndTime now. date2 := (DateAndTime fromString: (date printString)). date = date2 |
Ok,
this means it takes a while? :) In the meantime I try if I can get away with executionTime := DateAndTime fromString: (DateAndTime now printString). Now I shouldn't forget my sun glasses when going to work :) Norbert Am 22.03.2011 um 18:54 schrieb [hidden email]: > Status: Accepted > Owner: [hidden email] > Labels: Type-Defect Priority-Medium GLASS-Server Version-1.0-beta.8.6 > > New issue 254 by [hidden email]: DateAndTimes don't compare correctly > http://code.google.com/p/glassdb/issues/detail?id=254 > > for discussion see: > > http://forum.world.st/DateAndTime-problem-td3394257.html > > the basic example is: > > With the following change to DataAndTime: > > > DateAndTime class>>secondsSince2001 > > "^DateTime now asSecondsGmt - 3155760000." > ^ (System _timeGmtFloat - 978307200) asScaledDecimal: 3. > > the following doesn't behave as expected: > > > | date date2 | > date := DateAndTime now. > date2 := (DateAndTime fromString: (date printString)). > date = date2 > > |
In reply to this post by glassdb
Updates:
Status: Fixed Comment #1 on issue 254 by [hidden email]: DateAndTimes don't compare correctly http://code.google.com/p/glassdb/issues/detail?id=254 If you look closley: | date date2 | date := DateAndTime now. date2 := (DateAndTime fromString: (date printString)). { date. date2. date = date2} results in: anArray( 2011-03-22T11:49:51.581-07:00, 2011-03-22T11:49:51.581-07:00, false) which tells us that the printStrings are the same, so the instances of ScaledDecimal are equal (for all intents and purposes) ... but the implementation of ScaledDecimal>>#= is ah, quirky and two ScaledDecimals that print the same don't necessarily compare the same and this behavior is "traditional" in that that's the way most implementations work:) So in order to get ScaledDecimals to compare equal when they compare equal, you have to round to your desired precision, so DateAndTime class>>secondsSince2001 would look like this: secondsSince2001 "^DateTime now asSecondsGmt - 3155760000." ^ ((System _timeGmtFloat - 978307200) roundTo: 1/1000) asScaledDecimal: 3. Since this is the "expected" behavior for 2.0, there is no bug ... In 3.0 the GemStone ScaledDecimals that print the same _will_ compare_ equal! |
In reply to this post by NorbertHartl
On 03/22/2011 11:11 AM, Norbert Hartl wrote:
> Ok, > > this means it takes a while? :) Well, sort of... it means that I wasn't able to give you an immediate solution and I didn't want to forget about it ... It is unreliable for me to leave messages unread in my mail readers (an accidental mark all as read erases everything), so I use the Issue Tracking system as my todo list:) I did take a look and you should have already seen my answer:) > In the meantime I try if I can get away with > > executionTime := DateAndTime fromString: (DateAndTime now printString). That was the first thing I thought of, too:), but you can round the float to the right precision and then create a ScaledDecimal:) You could do the printString trick to compare the DateAndTimes, too ... it probably depends upon where you want to put the hack... > > Now I shouldn't forget my sun glasses when going to work :) > > Norbert > |
In reply to this post by glassdb
Am 22.03.2011 um 19:56 schrieb [hidden email]:
Does this mean that the ScaledDecimal>>= is implemented differently. The effect is that if you create a ScaledDecimal it compiles to numerator and denominator. The equals check just compares those two values it will report false if they are different. So in my case there were different numerator and denominator that caculate to the same value at the given precision and therefor result in the same printString. I'm not sure if roundTo: will automatically lead to the same numerator and denominator in every case. Either I need this assurance or a better ScaledDecimal>= implementation. What do you think? Norbert
|
Norbert,
I am not a mathematician, so I can't guarantee anything. I was under the impression that rounding by 1/1000 would result in an exact fraction for the ScaledDecimal which would imply that the same fraction would be used when the ScaledDecimal was created from a string ... Of course implementations hit corner cases. The only way to absolutely certain that the a DateAndTime created from a String will match the original DateAndTime is to use a String to create them both: DateAndTime fromString: DateAndTime now asString We figured that the roundTo: would work, but I figured that a ScaledDecimal would work:) earlier. As I mention in the email, you could use the printString in your comparison instead of #= and then there would be no need to round the ScaledDecimal ... You could also change the implemention of fromString: to avoid ScaledDecimal, but I'm not sure that would solve your problem without having to fudge other things ... So I think at this point you will have to pick your own poison:) Dale On 03/22/2011 12:47 PM, Norbert Hartl wrote: > > Am 22.03.2011 um 19:56 schrieb [hidden email] > <mailto:[hidden email]>: > >> Updates: >> Status: Fixed >> >> Comment #1 on issue 254 by [hidden email]: DateAndTimes don't >> compare correctly >> http://code.google.com/p/glassdb/issues/detail?id=254 >> >> If you look closley: >> >> >> | date date2 | >> date := DateAndTime now. >> date2 := (DateAndTime fromString: (date printString)). >> { date. date2. date = date2} >> >> results in: >> anArray( 2011-03-22T11:49:51.581-07:00, 2011-03-22T11:49:51.581-07:00, >> false) >> >> which tells us that the printStrings are the same, so the instances of >> ScaledDecimal are equal (for all intents and purposes) ... but the >> implementation of ScaledDecimal>>#= is ah, quirky and two >> ScaledDecimals that print the same don't necessarily compare the same >> and this behavior is "traditional" in that that's the way most >> implementations work:) >> >> So in order to get ScaledDecimals to compare equal when they compare >> equal, you have to round to your desired precision, so DateAndTime >> class>>secondsSince2001 would look like this: >> >> secondsSince2001 >> >> "^DateTime now asSecondsGmt - 3155760000." >> ^ ((System _timeGmtFloat - 978307200) roundTo: 1/1000) asScaledDecimal: 3. >> >> Since this is the "expected" behavior for 2.0, there is no bug ... In >> 3.0 the GemStone ScaledDecimals that print the same _will_ compare_ equal! > > Does this mean that the ScaledDecimal>>= is implemented differently. The > effect is that if you create a ScaledDecimal it compiles to numerator > and denominator. The equals check just compares those two values it will > report false if they are different. So in my case there were different > numerator and denominator that caculate to the same value at the given > precision and therefor result in the same printString. I'm not sure if > roundTo: will automatically lead to the same numerator and denominator > in every case. Either I need this assurance or a better ScaledDecimal>= > implementation. > > What do you think? > > Norbert |
Am 22.03.2011 um 21:22 schrieb Dale Henrichs: > Norbert, > > I am not a mathematician, so I can't guarantee anything. I was under the impression that rounding by 1/1000 would result in an exact fraction for the ScaledDecimal which would imply that the same fraction would be used when the ScaledDecimal was created from a string ... > > Of course implementations hit corner cases. The only way to absolutely certain that the a DateAndTime created from a String will match the original DateAndTime is to use a String to create them both: > > DateAndTime fromString: DateAndTime now asString > Or to use seconds for storage. > We figured that the roundTo: would work, but I figured that a ScaledDecimal would work:) earlier. > Yes, me too. And I was astonished that I used the same thing for weeks until the problem showed up. It is not that easy to reproduce and that makes me kind of uncertain. As you are a developer I don't need to explain this :) > As I mention in the email, you could use the printString in your comparison instead of #= and then there would be no need to round the ScaledDecimal ... > That is not possible. What I need is > comparison and that does not work with strings. Using a conversion to printString is not really feasible if used in the collection protocol. > You could also change the implemention of fromString: to avoid ScaledDecimal, but I'm not sure that would solve your problem without having to fudge other things ... > If avoiding ScaledDecimal means to use SmallDouble I'm pretty confident it won't help :) > So I think at this point you will have to pick your own poison:) > Let me phrase it like this: I hate it having to agree :) thanks, Norbert > Dale > On 03/22/2011 12:47 PM, Norbert Hartl wrote: >> >> Am 22.03.2011 um 19:56 schrieb [hidden email] >> <mailto:[hidden email]>: >> >>> Updates: >>> Status: Fixed >>> >>> Comment #1 on issue 254 by [hidden email]: DateAndTimes don't >>> compare correctly >>> http://code.google.com/p/glassdb/issues/detail?id=254 >>> >>> If you look closley: >>> >>> >>> | date date2 | >>> date := DateAndTime now. >>> date2 := (DateAndTime fromString: (date printString)). >>> { date. date2. date = date2} >>> >>> results in: >>> anArray( 2011-03-22T11:49:51.581-07:00, 2011-03-22T11:49:51.581-07:00, >>> false) >>> >>> which tells us that the printStrings are the same, so the instances of >>> ScaledDecimal are equal (for all intents and purposes) ... but the >>> implementation of ScaledDecimal>>#= is ah, quirky and two >>> ScaledDecimals that print the same don't necessarily compare the same >>> and this behavior is "traditional" in that that's the way most >>> implementations work:) >>> >>> So in order to get ScaledDecimals to compare equal when they compare >>> equal, you have to round to your desired precision, so DateAndTime >>> class>>secondsSince2001 would look like this: >>> >>> secondsSince2001 >>> >>> "^DateTime now asSecondsGmt - 3155760000." >>> ^ ((System _timeGmtFloat - 978307200) roundTo: 1/1000) asScaledDecimal: 3. >>> >>> Since this is the "expected" behavior for 2.0, there is no bug ... In >>> 3.0 the GemStone ScaledDecimals that print the same _will_ compare_ equal! >> >> Does this mean that the ScaledDecimal>>= is implemented differently. The >> effect is that if you create a ScaledDecimal it compiles to numerator >> and denominator. The equals check just compares those two values it will >> report false if they are different. So in my case there were different >> numerator and denominator that caculate to the same value at the given >> precision and therefor result in the same printString. I'm not sure if >> roundTo: will automatically lead to the same numerator and denominator >> in every case. Either I need this assurance or a better ScaledDecimal>= >> implementation. >> >> What do you think? >> >> Norbert > |
In reply to this post by Dale Henrichs
Am 22.03.2011 um 21:22 schrieb Dale Henrichs: > So I think at this point you will have to pick your own poison:) Well said. Testing creation of 100000 things gives in milliseconds 82 System _timeGmtFloat 2406 DateAndTime now (unaltered) 39806 DateAndTime now (with rounded and conversion to ScaledDecimal) Norbert |
Free forum by Nabble | Edit this page |