DateAndTime problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

DateAndTime problem

NorbertHartl
I've found a rather strange behaviour with DateAndTime. In my code I have commands that have an executionTime. They do

execute
   executionTime := DateAndTime now.
   ...

After that they are persisted. Today I recognized that the comparison between this DateAndTimes does not work as I would expect it. I'm not able to produce a test case because I don't know how to produce the circumstance. I can do in a workspace

| date |
date := DateAndTime now.
date > (DateAndTime fromString: (date asString))

which prints to false. If I do the same with an object fetched from the storage

| persistentDate |
persistentDate := ..access persistent command... executionTime.
persistentDate > (DateAndTime fromString: persistentDate asString)

it evaluates to true. I think I know the reason but I can't recreate it in the workspace.

DateAndTime now asSeconds class name

resolves to SmallDouble while

(DateAndTime fromString: (DateAndTime now asString)) asSeconds class name

resolves to ScaledDecimal. While comparing the dates the ScaledDecimal is coerced to a SmallDouble and the value is slightly different. However I'm unable to produce anything from the workspace to reproduce the problem.

Any hint is appreciated. And of course a way how to compare a DateAndTime object with a deserialized string version of a date. It was hard to see that comparison is based only on seconds anyway :)

thanks,

Norbert
Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

Max Leske
I think that I encountered the same thing before. I thought that Dale had fixed that. See the message thread "failing tests?"

Max


On 21.03.2011, at 18:45, Norbert Hartl wrote:

> I've found a rather strange behaviour with DateAndTime. In my code I have commands that have an executionTime. They do
>
> execute
>   executionTime := DateAndTime now.
>   ...
>
> After that they are persisted. Today I recognized that the comparison between this DateAndTimes does not work as I would expect it. I'm not able to produce a test case because I don't know how to produce the circumstance. I can do in a workspace
>
> | date |
> date := DateAndTime now.
> date > (DateAndTime fromString: (date asString))
>
> which prints to false. If I do the same with an object fetched from the storage
>
> | persistentDate |
> persistentDate := ..access persistent command... executionTime.
> persistentDate > (DateAndTime fromString: persistentDate asString)
>
> it evaluates to true. I think I know the reason but I can't recreate it in the workspace.
>
> DateAndTime now asSeconds class name
>
> resolves to SmallDouble while
>
> (DateAndTime fromString: (DateAndTime now asString)) asSeconds class name
>
> resolves to ScaledDecimal. While comparing the dates the ScaledDecimal is coerced to a SmallDouble and the value is slightly different. However I'm unable to produce anything from the workspace to reproduce the problem.
>
> Any hint is appreciated. And of course a way how to compare a DateAndTime object with a deserialized string version of a date. It was hard to see that comparison is based only on seconds anyway :)
>
> thanks,
>
> Norbert

Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

NorbertHartl

Am 21.03.2011 um 19:01 schrieb Max Leske:

> I think that I encountered the same thing before. I thought that Dale had fixed that. See the message thread "failing tests?"

I did not find any references that looks like the problem I reported.

Norbert

>
>
> On 21.03.2011, at 18:45, Norbert Hartl wrote:
>
>> I've found a rather strange behaviour with DateAndTime. In my code I have commands that have an executionTime. They do
>>
>> execute
>>  executionTime := DateAndTime now.
>>  ...
>>
>> After that they are persisted. Today I recognized that the comparison between this DateAndTimes does not work as I would expect it. I'm not able to produce a test case because I don't know how to produce the circumstance. I can do in a workspace
>>
>> | date |
>> date := DateAndTime now.
>> date > (DateAndTime fromString: (date asString))
>>
>> which prints to false. If I do the same with an object fetched from the storage
>>
>> | persistentDate |
>> persistentDate := ..access persistent command... executionTime.
>> persistentDate > (DateAndTime fromString: persistentDate asString)
>>
>> it evaluates to true. I think I know the reason but I can't recreate it in the workspace.
>>
>> DateAndTime now asSeconds class name
>>
>> resolves to SmallDouble while
>>
>> (DateAndTime fromString: (DateAndTime now asString)) asSeconds class name
>>
>> resolves to ScaledDecimal. While comparing the dates the ScaledDecimal is coerced to a SmallDouble and the value is slightly different. However I'm unable to produce anything from the workspace to reproduce the problem.
>>
>> Any hint is appreciated. And of course a way how to compare a DateAndTime object with a deserialized string version of a date. It was hard to see that comparison is based only on seconds anyway :)
>>
>> thanks,
>>
>> Norbert
>

Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

Max Leske
I got a testfailure a while back for #testDateArithmetic:

#testDateArithmetic
The failing line is: "self assert: Time now asDateAndTime  <= DateAndTime now".

"Time now asDateAndTime" evaluates to: 2011-02-01T21:01:51-08:00.
The number of seconds of this object are: 318315819.

"DateAndTime now" evaluates to: 2011-02-01T12:02:48.1668438911438-08:00
The number of seconds of this object are: 3,1828354650827408E+08.
The offset is the same for both objects.
The difference is a Duration of 0:08:59:59.2.

So why the crazy seconds?
The reason lies in DateAndTime>>secondsSince2001. The statement: "System _timeGmtFloat - 978307200" evaluates to: 3,1828371659105110E+08.
Even when truncated the SmallDouble value is much smaller than the SmallInt one.
My guess is again that there's a problem with the primitive for #_timeTmtFloat because the primitive used by Time class>>now seems to answer the correct value.

The test fails when comparing two DateAndTime objects (same as your problem, right?). In my case there were two different primitives at work, one answered SmallDouble, the other SmallInt.

I'm sorry if I should have put you on the wrong track. Just sounded very much like a similiar problem.

Max


On 21.03.2011, at 19:10, Norbert Hartl wrote:


Am 21.03.2011 um 19:01 schrieb Max Leske:

I think that I encountered the same thing before. I thought that Dale had fixed that. See the message thread "failing tests?"

I did not find any references that looks like the problem I reported.

Norbert



On 21.03.2011, at 18:45, Norbert Hartl wrote:

I've found a rather strange behaviour with DateAndTime. In my code I have commands that have an executionTime. They do

execute
executionTime := DateAndTime now.
...

After that they are persisted. Today I recognized that the comparison between this DateAndTimes does not work as I would expect it. I'm not able to produce a test case because I don't know how to produce the circumstance. I can do in a workspace

| date |
date := DateAndTime now.
date > (DateAndTime fromString: (date asString))

which prints to false. If I do the same with an object fetched from the storage

| persistentDate |
persistentDate := ..access persistent command... executionTime.
persistentDate > (DateAndTime fromString: persistentDate asString)

it evaluates to true. I think I know the reason but I can't recreate it in the workspace.

DateAndTime now asSeconds class name

resolves to SmallDouble while

(DateAndTime fromString: (DateAndTime now asString)) asSeconds class name

resolves to ScaledDecimal. While comparing the dates the ScaledDecimal is coerced to a SmallDouble and the value is slightly different. However I'm unable to produce anything from the workspace to reproduce the problem.

Any hint is appreciated. And of course a way how to compare a DateAndTime object with a deserialized string version of a date. It was hard to see that comparison is based only on seconds anyway :)

thanks,

Norbert



Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

NorbertHartl

Am 21.03.2011 um 19:58 schrieb Max Leske:

I got a testfailure a while back for #testDateArithmetic:

#testDateArithmetic
The failing line is: "self assert: Time now asDateAndTime  <= DateAndTime now".

"Time now asDateAndTime" evaluates to: 2011-02-01T21:01:51-08:00.
The number of seconds of this object are: 318315819.

"DateAndTime now" evaluates to: 2011-02-01T12:02:48.1668438911438-08:00
The number of seconds of this object are: 3,1828354650827408E+08.
The offset is the same for both objects.
The difference is a Duration of 0:08:59:59.2.

So why the crazy seconds?
The reason lies in DateAndTime>>secondsSince2001. The statement: "System _timeGmtFloat - 978307200" evaluates to: 3,1828371659105110E+08.
Even when truncated the SmallDouble value is much smaller than the SmallInt one.
My guess is again that there's a problem with the primitive for #_timeTmtFloat because the primitive used by Time class>>now seems to answer the correct value.

The test fails when comparing two DateAndTime objects (same as your problem, right?). In my case there were two different primitives at work, one answered SmallDouble, the other SmallInt.

I'm sorry if I should have put you on the wrong track. Just sounded very much like a similiar problem.


Oh, I did not see this. I'm sorry. In fact it seems to be the same problem. I don't have a glue how to treat this, yet. And I'm not sure if fractions or floats/doubles are the perfect hit for representing time. Well, I'm sure there are not ;) Bad luck for me a scale of only seconds is too coarse grained for me. So get rid of DateAndTime and use millisecond rounded time might be best as intermediate

Norbert


On 21.03.2011, at 19:10, Norbert Hartl wrote:


Am 21.03.2011 um 19:01 schrieb Max Leske:

I think that I encountered the same thing before. I thought that Dale had fixed that. See the message thread "failing tests?"

I did not find any references that looks like the problem I reported.

Norbert



On 21.03.2011, at 18:45, Norbert Hartl wrote:

I've found a rather strange behaviour with DateAndTime. In my code I have commands that have an executionTime. They do

execute
executionTime := DateAndTime now.
...

After that they are persisted. Today I recognized that the comparison between this DateAndTimes does not work as I would expect it. I'm not able to produce a test case because I don't know how to produce the circumstance. I can do in a workspace

| date |
date := DateAndTime now.
date > (DateAndTime fromString: (date asString))

which prints to false. If I do the same with an object fetched from the storage

| persistentDate |
persistentDate := ..access persistent command... executionTime.
persistentDate > (DateAndTime fromString: persistentDate asString)

it evaluates to true. I think I know the reason but I can't recreate it in the workspace.

DateAndTime now asSeconds class name

resolves to SmallDouble while

(DateAndTime fromString: (DateAndTime now asString)) asSeconds class name

resolves to ScaledDecimal. While comparing the dates the ScaledDecimal is coerced to a SmallDouble and the value is slightly different. However I'm unable to produce anything from the workspace to reproduce the problem.

Any hint is appreciated. And of course a way how to compare a DateAndTime object with a deserialized string version of a date. It was hard to see that comparison is based only on seconds anyway :)

thanks,

Norbert




Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

Dale Henrichs
In reply to this post by NorbertHartl
Norbert and Max,

Max's problem had to do with comparing DateAndTime and Time and is
covered in Issue 228[1], so Norbert's case is slightly different.

Norbert, your problem is ultimately stemming from the fact that a Float
cannot be accurately represented by it's printString.

DateAndTime can use different classes to represent the number of seconds
since the epoch. The default is to store seconds as a SmallDouble.

When you create a DateAndTime from a String, the desire is to preserve
the exact time specified in the String, so ScaledDecimal is used to
represent the seconds. ScaledDecimal would be the choice to preserve
equality across serialization steps.

You _can_ change the precision used in DateAndTime by overriding
DateAndTime class>>secondsSince2001 to return a ScaledDecimal with the
number of digits of precision needed for your application (the
SmallDouble gives you way more precision than you need)...then you will
be able to exactly deserialize the DateAndTime.

Dale

[1] http://code.google.com/p/glassdb/issues/detail?id=228

On 03/21/2011 10:45 AM, Norbert Hartl wrote:

> I've found a rather strange behaviour with DateAndTime. In my code I
> have commands that have an executionTime. They do
>
> execute executionTime := DateAndTime now. ...
>
> After that they are persisted. Today I recognized that the comparison
> between this DateAndTimes does not work as I would expect it. I'm not
> able to produce a test case because I don't know how to produce the
> circumstance. I can do in a workspace
>
> | date | date := DateAndTime now. date>  (DateAndTime fromString:
> (date asString))
>
> which prints to false. If I do the same with an object fetched from
> the storage
>
> | persistentDate | persistentDate := ..access persistent command...
> executionTime. persistentDate>  (DateAndTime fromString:
> persistentDate asString)
>
> it evaluates to true. I think I know the reason but I can't recreate
> it in the workspace.
>
> DateAndTime now asSeconds class name
>
> resolves to SmallDouble while
>
> (DateAndTime fromString: (DateAndTime now asString)) asSeconds class
> name
>
> resolves to ScaledDecimal. While comparing the dates the
> ScaledDecimal is coerced to a SmallDouble and the value is slightly
> different. However I'm unable to produce anything from the workspace
> to reproduce the problem.
>
> Any hint is appreciated. And of course a way how to compare a
> DateAndTime object with a deserialized string version of a date. It
> was hard to see that comparison is based only on seconds anyway :)
>
> thanks,
>
> Norbert

Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

NorbertHartl

Am 21.03.2011 um 20:41 schrieb Dale Henrichs:

Norbert and Max,

Max's problem had to do with comparing DateAndTime and Time and is
covered in Issue 228[1], so Norbert's case is slightly different.

Norbert, your problem is ultimately stemming from the fact that a Float
cannot be accurately represented by it's printString.

Agreed.

DateAndTime can use different classes to represent the number of seconds
since the epoch. The default is to store seconds as a SmallDouble.

When you create a DateAndTime from a String, the desire is to preserve
the exact time specified in the String, so ScaledDecimal is used to
represent the seconds. ScaledDecimal would be the choice to preserve equality across serialization steps.

Ok. It just made me wonder why this case occurrs so rare. With all my tests I couldn't produce a second case in the workspace. I could only test because I had a persisted example I could use over and over again.

You _can_ change the precision used in DateAndTime by overriding DateAndTime class>>secondsSince2001 to return a ScaledDecimal with the number of digits of precision needed for your application (the SmallDouble gives you way more precision than you need)...then you will be able to exactly deserialize the DateAndTime.

Thanks. I solved it. I don't like method overrides. They kill you sooner or later. I just added a method extension

asDateAndTimeScaled: aNumber
^ DateAndTime secondsUTC: (seconds asScaledDecimal: aNumber) offset: nil

So my code changes from

executionTime := DateAndTime now.

to

executionTime := DateAndTime now asDateAndTimeScaled: self precisionScale

It is neither pretty nor bad so I can live with it.

Thanks again,

Norbert

[1] http://code.google.com/p/glassdb/issues/detail?id=228

On 03/21/2011 10:45 AM, Norbert Hartl wrote:
I've found a rather strange behaviour with DateAndTime. In my code I
have commands that have an executionTime. They do

execute executionTime := DateAndTime now. ...

After that they are persisted. Today I recognized that the comparison
between this DateAndTimes does not work as I would expect it. I'm not
able to produce a test case because I don't know how to produce the
circumstance. I can do in a workspace

| date | date := DateAndTime now. date>  (DateAndTime fromString:
(date asString))

which prints to false. If I do the same with an object fetched from
the storage

| persistentDate | persistentDate := ..access persistent command...
executionTime. persistentDate>  (DateAndTime fromString:
persistentDate asString)

it evaluates to true. I think I know the reason but I can't recreate
it in the workspace.

DateAndTime now asSeconds class name

resolves to SmallDouble while

(DateAndTime fromString: (DateAndTime now asString)) asSeconds class
name

resolves to ScaledDecimal. While comparing the dates the
ScaledDecimal is coerced to a SmallDouble and the value is slightly
different. However I'm unable to produce anything from the workspace
to reproduce the problem.

Any hint is appreciated. And of course a way how to compare a
DateAndTime object with a deserialized string version of a date. It
was hard to see that comparison is based only on seconds anyway :)

thanks,

Norbert


Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

Dale Henrichs
Norbert,

Yeah, I agree that overrides are nasty ... but they are necessary... in
your case they aren't necessary, so that's good.

Dale


On 03/22/2011 08:45 AM, Norbert Hartl wrote:

>
> Am 21.03.2011 um 20:41 schrieb Dale Henrichs:
>
>> Norbert and Max,
>>
>> Max's problem had to do with comparing DateAndTime and Time and is
>> covered in Issue 228[1], so Norbert's case is slightly different.
>>
>> Norbert, your problem is ultimately stemming from the fact that a Float
>> cannot be accurately represented by it's printString.
>>
> Agreed.
>
>> DateAndTime can use different classes to represent the number of seconds
>> since the epoch. The default is to store seconds as a SmallDouble.
>>
>> When you create a DateAndTime from a String, the desire is to preserve
>> the exact time specified in the String, so ScaledDecimal is used to
>> represent the seconds. ScaledDecimal would be the choice to preserve
>> equality across serialization steps.
>>
> Ok. It just made me wonder why this case occurrs so rare. With all my
> tests I couldn't produce a second case in the workspace. I could only
> test because I had a persisted example I could use over and over again.
>
>> You _can_ change the precision used in DateAndTime by overriding
>> DateAndTime class>>secondsSince2001 to return a ScaledDecimal with the
>> number of digits of precision needed for your application (the
>> SmallDouble gives you way more precision than you need)...then you
>> will be able to exactly deserialize the DateAndTime.
>>
> Thanks. I solved it. I don't like method overrides. They kill you sooner
> or later. I just added a method extension
>
> asDateAndTimeScaled: aNumber
> ^ DateAndTime secondsUTC: (seconds asScaledDecimal: aNumber) offset: nil
>
> So my code changes from
>
> executionTime := DateAndTime now.
>
> to
>
> executionTime := DateAndTime now asDateAndTimeScaled: self precisionScale
>
> It is neither pretty nor bad so I can live with it.
>
> Thanks again,
>
> Norbert
>>
>> [1] http://code.google.com/p/glassdb/issues/detail?id=228
>>
>> On 03/21/2011 10:45 AM, Norbert Hartl wrote:
>>> I've found a rather strange behaviour with DateAndTime. In my code I
>>> have commands that have an executionTime. They do
>>>
>>> execute executionTime := DateAndTime now. ...
>>>
>>> After that they are persisted. Today I recognized that the comparison
>>> between this DateAndTimes does not work as I would expect it. I'm not
>>> able to produce a test case because I don't know how to produce the
>>> circumstance. I can do in a workspace
>>>
>>> | date | date := DateAndTime now. date> (DateAndTime fromString:
>>> (date asString))
>>>
>>> which prints to false. If I do the same with an object fetched from
>>> the storage
>>>
>>> | persistentDate | persistentDate := ..access persistent command...
>>> executionTime. persistentDate> (DateAndTime fromString:
>>> persistentDate asString)
>>>
>>> it evaluates to true. I think I know the reason but I can't recreate
>>> it in the workspace.
>>>
>>> DateAndTime now asSeconds class name
>>>
>>> resolves to SmallDouble while
>>>
>>> (DateAndTime fromString: (DateAndTime now asString)) asSeconds class
>>> name
>>>
>>> resolves to ScaledDecimal. While comparing the dates the
>>> ScaledDecimal is coerced to a SmallDouble and the value is slightly
>>> different. However I'm unable to produce anything from the workspace
>>> to reproduce the problem.
>>>
>>> Any hint is appreciated. And of course a way how to compare a
>>> DateAndTime object with a deserialized string version of a date. It
>>> was hard to see that comparison is based only on seconds anyway :)
>>>
>>> thanks,
>>>
>>> Norbert
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

NorbertHartl
In reply to this post by NorbertHartl
Dale,

the problem is not solved. I can produce DateAndTime objects which both carry a ScaledDecimal. But the numerator and denominator are somehow created differently so that the DateAndTimes are not equal. Although the string is equal while the objects are not. Scale is at 3 which is not a lot.

Any ideas?

Norbert

Am 22.03.2011 um 16:45 schrieb Norbert Hartl:


Am 21.03.2011 um 20:41 schrieb Dale Henrichs:

Norbert and Max,

Max's problem had to do with comparing DateAndTime and Time and is
covered in Issue 228[1], so Norbert's case is slightly different.

Norbert, your problem is ultimately stemming from the fact that a Float
cannot be accurately represented by it's printString.

Agreed.

DateAndTime can use different classes to represent the number of seconds
since the epoch. The default is to store seconds as a SmallDouble.

When you create a DateAndTime from a String, the desire is to preserve
the exact time specified in the String, so ScaledDecimal is used to
represent the seconds. ScaledDecimal would be the choice to preserve equality across serialization steps.

Ok. It just made me wonder why this case occurrs so rare. With all my tests I couldn't produce a second case in the workspace. I could only test because I had a persisted example I could use over and over again.

You _can_ change the precision used in DateAndTime by overriding DateAndTime class>>secondsSince2001 to return a ScaledDecimal with the number of digits of precision needed for your application (the SmallDouble gives you way more precision than you need)...then you will be able to exactly deserialize the DateAndTime.

Thanks. I solved it. I don't like method overrides. They kill you sooner or later. I just added a method extension

asDateAndTimeScaled: aNumber
^ DateAndTime secondsUTC: (seconds asScaledDecimal: aNumber) offset: nil

So my code changes from

executionTime := DateAndTime now.

to

executionTime := DateAndTime now asDateAndTimeScaled: self precisionScale

It is neither pretty nor bad so I can live with it.

Thanks again,

Norbert

[1] http://code.google.com/p/glassdb/issues/detail?id=228

On 03/21/2011 10:45 AM, Norbert Hartl wrote:
I've found a rather strange behaviour with DateAndTime. In my code I
have commands that have an executionTime. They do

execute executionTime := DateAndTime now. ...

After that they are persisted. Today I recognized that the comparison
between this DateAndTimes does not work as I would expect it. I'm not
able to produce a test case because I don't know how to produce the
circumstance. I can do in a workspace

| date | date := DateAndTime now. date>  (DateAndTime fromString:
(date asString))

which prints to false. If I do the same with an object fetched from
the storage

| persistentDate | persistentDate := ..access persistent command...
executionTime. persistentDate>  (DateAndTime fromString:
persistentDate asString)

it evaluates to true. I think I know the reason but I can't recreate
it in the workspace.

DateAndTime now asSeconds class name

resolves to SmallDouble while

(DateAndTime fromString: (DateAndTime now asString)) asSeconds class
name

resolves to ScaledDecimal. While comparing the dates the
ScaledDecimal is coerced to a SmallDouble and the value is slightly
different. However I'm unable to produce anything from the workspace
to reproduce the problem.

Any hint is appreciated. And of course a way how to compare a
DateAndTime object with a deserialized string version of a date. It
was hard to see that comparison is based only on seconds anyway :)

thanks,

Norbert



Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

Dale Henrichs
Norbert,

Do you have examples that I can look at?

Dale

On 03/22/2011 10:07 AM, Norbert Hartl wrote:

> Dale,
>
> the problem is not solved. I can produce DateAndTime objects which both
> carry a ScaledDecimal. But the numerator and denominator are somehow
> created differently so that the DateAndTimes are not equal. Although the
> string is equal while the objects are not. Scale is at 3 which is not a lot.
>
> Any ideas?
>
> Norbert
>
> Am 22.03.2011 um 16:45 schrieb Norbert Hartl:
>
>>
>> Am 21.03.2011 um 20:41 schrieb Dale Henrichs:
>>
>>> Norbert and Max,
>>>
>>> Max's problem had to do with comparing DateAndTime and Time and is
>>> covered in Issue 228[1], so Norbert's case is slightly different.
>>>
>>> Norbert, your problem is ultimately stemming from the fact that a Float
>>> cannot be accurately represented by it's printString.
>>>
>> Agreed.
>>
>>> DateAndTime can use different classes to represent the number of seconds
>>> since the epoch. The default is to store seconds as a SmallDouble.
>>>
>>> When you create a DateAndTime from a String, the desire is to preserve
>>> the exact time specified in the String, so ScaledDecimal is used to
>>> represent the seconds. ScaledDecimal would be the choice to preserve
>>> equality across serialization steps.
>>>
>> Ok. It just made me wonder why this case occurrs so rare. With all my
>> tests I couldn't produce a second case in the workspace. I could only
>> test because I had a persisted example I could use over and over again.
>>
>>> You _can_ change the precision used in DateAndTime by overriding
>>> DateAndTime class>>secondsSince2001 to return a ScaledDecimal with
>>> the number of digits of precision needed for your application (the
>>> SmallDouble gives you way more precision than you need)...then you
>>> will be able to exactly deserialize the DateAndTime.
>>>
>> Thanks. I solved it. I don't like method overrides. They kill you
>> sooner or later. I just added a method extension
>>
>> asDateAndTimeScaled: aNumber
>> ^ DateAndTime secondsUTC: (seconds asScaledDecimal: aNumber) offset: nil
>>
>> So my code changes from
>>
>> executionTime := DateAndTime now.
>>
>> to
>>
>> executionTime := DateAndTime now asDateAndTimeScaled: self precisionScale
>>
>> It is neither pretty nor bad so I can live with it.
>>
>> Thanks again,
>>
>> Norbert
>>>
>>> [1] http://code.google.com/p/glassdb/issues/detail?id=228
>>>
>>> On 03/21/2011 10:45 AM, Norbert Hartl wrote:
>>>> I've found a rather strange behaviour with DateAndTime. In my code I
>>>> have commands that have an executionTime. They do
>>>>
>>>> execute executionTime := DateAndTime now. ...
>>>>
>>>> After that they are persisted. Today I recognized that the comparison
>>>> between this DateAndTimes does not work as I would expect it. I'm not
>>>> able to produce a test case because I don't know how to produce the
>>>> circumstance. I can do in a workspace
>>>>
>>>> | date | date := DateAndTime now. date> (DateAndTime fromString:
>>>> (date asString))
>>>>
>>>> which prints to false. If I do the same with an object fetched from
>>>> the storage
>>>>
>>>> | persistentDate | persistentDate := ..access persistent command...
>>>> executionTime. persistentDate> (DateAndTime fromString:
>>>> persistentDate asString)
>>>>
>>>> it evaluates to true. I think I know the reason but I can't recreate
>>>> it in the workspace.
>>>>
>>>> DateAndTime now asSeconds class name
>>>>
>>>> resolves to SmallDouble while
>>>>
>>>> (DateAndTime fromString: (DateAndTime now asString)) asSeconds class
>>>> name
>>>>
>>>> resolves to ScaledDecimal. While comparing the dates the
>>>> ScaledDecimal is coerced to a SmallDouble and the value is slightly
>>>> different. However I'm unable to produce anything from the workspace
>>>> to reproduce the problem.
>>>>
>>>> Any hint is appreciated. And of course a way how to compare a
>>>> DateAndTime object with a deserialized string version of a date. It
>>>> was hard to see that comparison is based only on seconds anyway :)
>>>>
>>>> thanks,
>>>>
>>>> Norbert
>>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: DateAndTime problem

NorbertHartl
Dale,

I changed as you advized

DateAndTime class>>secondsSince2001

        "^DateTime now asSecondsGmt - 3155760000."
        ^ (System _timeGmtFloat - 978307200) asScaledDecimal: 3.

If you then evaluate

| date date2  |
date :=  DateAndTime now.
date2 :=  (DateAndTime fromString: (date printString)).
date = date2

it resolves to false.

Norbert

Am 22.03.2011 um 18:17 schrieb Dale Henrichs:

> Norbert,
>
> Do you have examples that I can look at?
>
> Dale
>
> On 03/22/2011 10:07 AM, Norbert Hartl wrote:
>> Dale,
>>
>> the problem is not solved. I can produce DateAndTime objects which both
>> carry a ScaledDecimal. But the numerator and denominator are somehow
>> created differently so that the DateAndTimes are not equal. Although the
>> string is equal while the objects are not. Scale is at 3 which is not a lot.
>>
>> Any ideas?
>>
>> Norbert
>>
>> Am 22.03.2011 um 16:45 schrieb Norbert Hartl:
>>
>>>
>>> Am 21.03.2011 um 20:41 schrieb Dale Henrichs:
>>>
>>>> Norbert and Max,
>>>>
>>>> Max's problem had to do with comparing DateAndTime and Time and is
>>>> covered in Issue 228[1], so Norbert's case is slightly different.
>>>>
>>>> Norbert, your problem is ultimately stemming from the fact that a Float
>>>> cannot be accurately represented by it's printString.
>>>>
>>> Agreed.
>>>
>>>> DateAndTime can use different classes to represent the number of seconds
>>>> since the epoch. The default is to store seconds as a SmallDouble.
>>>>
>>>> When you create a DateAndTime from a String, the desire is to preserve
>>>> the exact time specified in the String, so ScaledDecimal is used to
>>>> represent the seconds. ScaledDecimal would be the choice to preserve
>>>> equality across serialization steps.
>>>>
>>> Ok. It just made me wonder why this case occurrs so rare. With all my
>>> tests I couldn't produce a second case in the workspace. I could only
>>> test because I had a persisted example I could use over and over again.
>>>
>>>> You _can_ change the precision used in DateAndTime by overriding
>>>> DateAndTime class>>secondsSince2001 to return a ScaledDecimal with
>>>> the number of digits of precision needed for your application (the
>>>> SmallDouble gives you way more precision than you need)...then you
>>>> will be able to exactly deserialize the DateAndTime.
>>>>
>>> Thanks. I solved it. I don't like method overrides. They kill you
>>> sooner or later. I just added a method extension
>>>
>>> asDateAndTimeScaled: aNumber
>>> ^ DateAndTime secondsUTC: (seconds asScaledDecimal: aNumber) offset: nil
>>>
>>> So my code changes from
>>>
>>> executionTime := DateAndTime now.
>>>
>>> to
>>>
>>> executionTime := DateAndTime now asDateAndTimeScaled: self precisionScale
>>>
>>> It is neither pretty nor bad so I can live with it.
>>>
>>> Thanks again,
>>>
>>> Norbert
>>>>
>>>> [1] http://code.google.com/p/glassdb/issues/detail?id=228
>>>>
>>>> On 03/21/2011 10:45 AM, Norbert Hartl wrote:
>>>>> I've found a rather strange behaviour with DateAndTime. In my code I
>>>>> have commands that have an executionTime. They do
>>>>>
>>>>> execute executionTime := DateAndTime now. ...
>>>>>
>>>>> After that they are persisted. Today I recognized that the comparison
>>>>> between this DateAndTimes does not work as I would expect it. I'm not
>>>>> able to produce a test case because I don't know how to produce the
>>>>> circumstance. I can do in a workspace
>>>>>
>>>>> | date | date := DateAndTime now. date> (DateAndTime fromString:
>>>>> (date asString))
>>>>>
>>>>> which prints to false. If I do the same with an object fetched from
>>>>> the storage
>>>>>
>>>>> | persistentDate | persistentDate := ..access persistent command...
>>>>> executionTime. persistentDate> (DateAndTime fromString:
>>>>> persistentDate asString)
>>>>>
>>>>> it evaluates to true. I think I know the reason but I can't recreate
>>>>> it in the workspace.
>>>>>
>>>>> DateAndTime now asSeconds class name
>>>>>
>>>>> resolves to SmallDouble while
>>>>>
>>>>> (DateAndTime fromString: (DateAndTime now asString)) asSeconds class
>>>>> name
>>>>>
>>>>> resolves to ScaledDecimal. While comparing the dates the
>>>>> ScaledDecimal is coerced to a SmallDouble and the value is slightly
>>>>> different. However I'm unable to produce anything from the workspace
>>>>> to reproduce the problem.
>>>>>
>>>>> Any hint is appreciated. And of course a way how to compare a
>>>>> DateAndTime object with a deserialized string version of a date. It
>>>>> was hard to see that comparison is based only on seconds anyway :)
>>>>>
>>>>> thanks,
>>>>>
>>>>> Norbert
>>>>
>>>
>>
>