[squeak-dev] The Inbox: Chronology-Core-cmm.14.mcz

Chris Cunningham cunningham.cb at gmail.com
Thu Oct 18 19:06:31 UTC 2018


On Thu, Oct 18, 2018 at 10:27 AM Bert Freudenberg <bert at freudenbergs.de>
wrote:

> I'm not sure this is right.
>
> The current implementation comes from the "trunk thinks its tomorrow"
> discussion starting on 17 Feb 2016. As a result we introduced the
> "noTimezone" notion: a date without timezone compares equal to the same
> date in any time zone. At some point this made all the tests green.
>
True. But we were missing some tests (we should have a test the check
everywhere we defined #= to validate that equal objects also have equal
#hash).
As a consequence of that change, the following also happens:
   dates := { Date today.  DateAndTime now asDate }.
   dates first = dates second. "=true"
   dates asSet size. "=2"
Also, using dates as keys in Dictionaries might not work correctly, either.

We could fix these issues by altering #hash so that equal dates hash
equally - say, hashing ticks and maybe duration:
hash
   | ticks |
   ticks := start ticks.
   ^((ticks second // 86400 + ticks first) hashMultiply bitXor: ticks
second \\ 86400 bitXor: ticks third)
      + duration hash
 but explicitly ignoring offset.  This would "work" such that any date with
the same starting time (ignoring offset) would have the same hash.  The Set
example above would resolve down to 1, but dates with different offsets
would still be present in the Set (since that relies on #=, which would be
different in this case).

However, if we used Dates as a key in Dictionary, then the different Dates
with offsets will work fine, but the Date without offset will map to the
first date key in the chain for the same hash key, but not the others.
This invokes weird behaviour like:
  |dict|
  dict := Dictionary new: 3.
  dict
at: (DateAndTime now offset: 3 hours) asDate put: '3 hours';
at: (DateAndTime now offset: -6 hours) asDate put: '-6 hours'.
  dict at: Date today. "=> '3 hours' "
  dict removeKey: (DateAndTime now offset: 3 hours) asDate.
  dict at: Date today. "=> '-6 hours' "

Not ideal.  (Of course, this is how Dates behave for us today as well.
Even weirder if you put the Date today in as a key first - unpredictable
results ensue.)

That's why I like this change - I can't think of a better one.  Except
maybe having 2 Date classes like Richard is suggesting.

-cbc

>
> - Bert -
>
> On Wed, Oct 17, 2018 at 8:53 PM Chris Cunningham <cunningham.cb at gmail.com>
> wrote:
>
>> I like this.
>>
>> Although I notice that the comparison makes sure that the classes are the
>> same - so a Timespan starting at the exact same time as a Date and with 24
>> hour duration is not the same as a Date with the exact same values.
>>
>> This would allow further speedups if Date, Week, Month, and Year if we
>> wanted - just drop the comparison of duration in those classes.  (The
>> general case is still needed to tell Timespan apart from Schedule.)
>>
>> If you did that, you probably also want to re-implement hash as well -
>> simplifying it the same way.
>>
>> -cbc
>>
>> On Wed, Oct 17, 2018 at 8:07 PM <commits at source.squeak.org> wrote:
>>
>>> Chris Muller uploaded a new version of Chronology-Core to project The
>>> Inbox:
>>> http://source.squeak.org/inbox/Chronology-Core-cmm.14.mcz
>>>
>>> ==================== Summary ====================
>>>
>>> Name: Chronology-Core-cmm.14
>>> Author: cmm
>>> Time: 17 October 2018, 10:07:14.485014 pm
>>> UUID: 5d93900c-4a4e-4a4e-80f3-800dbdb07d0b
>>> Ancestors: Chronology-Core-tcj.12
>>>
>>> - A fix and optimization of Timespan>>#=.  Both elements being compared
>>> must have the same timezone (or same state of #noTimezone) in order to take
>>> advantage of the optimized #hasEqualTicks: comparison.  Otherwise (if
>>> different timezones), a full comparison of their starts (via #=) is needed.
>>> - There was a mention of this optimization put into the class comment.
>>> This level of detail may be a bit tedious for users to read at that level,
>>> so Brents original comment was restored.
>>>
>>> =============== Diff against Chronology-Core-tcj.12 ===============
>>>
>>> Item was changed:
>>>   Magnitude subclass: #Timespan
>>>         instanceVariableNames: 'start duration'
>>>         classVariableNames: ''
>>>         poolDictionaries: ''
>>>         category: 'Chronology-Core'!
>>>
>>> + !Timespan commentStamp: 'cmm 10/17/2018 22:00' prior: 0!
>>> + I represent a duration starting on a specific DateAndTime.!
>>> - !Timespan commentStamp: 'bf 2/18/2016 14:43' prior: 0!
>>> - I represent a duration starting on a specific DateAndTime.
>>> -
>>> - If my start has an offset identical to my #defaultOffset then
>>> comparisons ignore timezone offset.!
>>>
>>> Item was changed:
>>>   ----- Method: Timespan>>= (in category 'ansi protocol') -----
>>>   = comparand
>>> +     ^ self class = comparand class
>>> +         and: [(((self noTimezone and: [comparand noTimezone]) or:
>>> [self start offset = comparand start offset])
>>> +             ifTrue: [ self start hasEqualTicks: comparand start ]
>>> +             ifFalse: [ self start = comparand start ])
>>> +         and: [ self duration = comparand duration ] ]
>>> -       ^ self class = comparand class
>>> -               and: [((self noTimezone or: [ comparand noTimezone ])
>>> -                       ifTrue: [ self start hasEqualTicks: comparand
>>> start ]
>>> -                       ifFalse: [ self start = comparand start ])
>>> -               and: [ self duration = comparand duration ] ]
>>>   .!
>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20181018/ac63281e/attachment-0001.html>


More information about the Squeak-dev mailing list