My problem - use Dates as Dictionary keys - shortly:
d1 := Date today translateToUTC. d2 := Date today. d1 = d2. (true!) d := Dictionary new. d at: d1 put: 1. d at: d1. (ok) d at: d2. (bad - key not found) --- pf |
Hi Petr,
On Tue, 16 Oct 2018 at 21:25, Petr Fischer via Pharo-users <[hidden email]> wrote: > > My problem - use Dates as Dictionary keys - shortly: > > d1 := Date today translateToUTC. > d2 := Date today. > > d1 = d2. (true!) Which timezone are you in? CEDT (UTC+0200) gives false for this. Date is implemented primarily as a timespan, so days in different timezones are considered different. If you do: | d1 d2 | d1 := Date today translateTo: (TimeZone abbreviated: 'UTC') offset. d2 := Date today translateTo: (TimeZone abbreviated: 'EST') offset. { d1 = d2. d1 equals: d2 } You can see the difference. Of course, this doesn't help with using Date as a key in a dictionary. Probably your best option is to look at Sven's excellent ZTimezone package (although I haven't tested it in this scenario). I can't find the repository right now (I think Sven moved it to github). Sven? Cheers, Alistair > d := Dictionary new. > d at: d1 put: 1. > > d at: d1. (ok) > d at: d2. (bad - key not found) > > --- > > pf > |
In reply to this post by Pharo Smalltalk Users mailing list
> On 16 Oct 2018, at 19:53, Petr Fischer via Pharo-users <[hidden email]> wrote: > > > From: Petr Fischer <[hidden email]> > Subject: Dictionary and Date as keys > Date: 16 October 2018 at 19:53:40 GMT+2 > To: [hidden email] > > > My problem - use Dates as Dictionary keys - shortly: > > d1 := Date today translateToUTC. > d2 := Date today. > > d1 = d2. (true!) Hmm, no, for me (Pharo 7) Date today = Date today translateToUTC is false as it should be. > d := Dictionary new. > d at: d1 put: 1. > > d at: d1. (ok) > d at: d2. (bad - key not found) > > --- > > pf > > > |
In reply to this post by alistairgrant
> On 16 Oct 2018, at 22:27, Alistair Grant <[hidden email]> wrote: > > Hi Petr, > > On Tue, 16 Oct 2018 at 21:25, Petr Fischer via Pharo-users > <[hidden email]> wrote: >> >> My problem - use Dates as Dictionary keys - shortly: >> >> d1 := Date today translateToUTC. >> d2 := Date today. >> >> d1 = d2. (true!) > > Which timezone are you in? > > CEDT (UTC+0200) gives false for this. > > Date is implemented primarily as a timespan, so days in different > timezones are considered different. If you do: > > | d1 d2 | > > d1 := Date today translateTo: (TimeZone abbreviated: 'UTC') offset. > d2 := Date today translateTo: (TimeZone abbreviated: 'EST') offset. > > { d1 = d2. d1 equals: d2 } > > > You can see the difference. > > Of course, this doesn't help with using Date as a key in a dictionary. > Probably your best option is to look at Sven's excellent ZTimezone > package (although I haven't tested it in this scenario). > > I can't find the repository right now (I think Sven moved it to github). Sven? It is called ZTimestamp and it lives in various places, for example: https://github.com/svenvc/ztimestamp > Cheers, > Alistair > > > >> d := Dictionary new. >> d at: d1 put: 1. >> >> d at: d1. (ok) >> d at: d2. (bad - key not found) >> >> --- >> >> pf >> > |
There is an elephant in the room. Historically and in Smalltalks such as GNU Smalltalk, Smalltalk/X, my Smalltalk->C system, VisualAge Smalltalk, and VisualWOrks, a Date is *not* a TimeSpan and is *not* associated with a time zone or a zone offset. It's generally a direct subclass of Magnitude. And this was originally true in Squeak as well. I just had a look at SqueakV2.source to verify that. At some point subsequent to the 2.x series, Squeak made an incompatible and to me incomprehensible change, with the result that "Date" in today's Squeak and Pharo is incompatible with every other Smalltalk I've been able to check: it does not mean the same thing any more and cannot be used the same ways. The "classic" semantics is that a Date represents a cultural item, a day in the proleptic Gregorian calendar, without reference to any particular locality. For example, my most recent birthday was 2018-10-11, and it would have been the same *date* but not the same *timespan* no matter where I was in the world. The USA celebrated President's day on 2018-02-19 this year, and it was the same *date* in every state, but by no means the same *timespan*. Now, granting the utility of a class to represent the timespan associated with a date in a given timezone, the obvious way to introduce it would have been to introduce a new DateInZone class. Sadly, in Squeak the Date class was changed incompatibly to take that role, with nothing left to do what Date usefully did (and still does elsewhere). So now we have the problem that the original poster wanted to do something perfectly sensible that works in nearly every other Smalltalk and used to work in Squeak, but it doesn't work in Pharo. In this situation, I'd be strongly inclined to port say GNU Smalltalk's Date class, renaming it to CompatibleDate, add a global variable DateInZone, and add methods CompatibleDate>>inZone: DateInZone>>sansZone On Wed, 17 Oct 2018 at 09:44, Sven Van Caekenberghe <[hidden email]> wrote:
|
> On 17 Oct 2018, at 13:07, Richard O'Keefe <[hidden email]> wrote: > > There is an elephant in the room. Historically and in Smalltalks such as > GNU Smalltalk, Smalltalk/X, my Smalltalk->C system, VisualAge Smalltalk, > and VisualWOrks, a Date is *not* a TimeSpan and is *not* associated with > a time zone or a zone offset. It's generally a direct subclass of > Magnitude. And this was originally true in Squeak as well. I just had a > look at SqueakV2.source to verify that. > > At some point subsequent to the 2.x series, Squeak made an incompatible > and to me incomprehensible change, with the result that "Date" in today's > Squeak and Pharo is incompatible with every other Smalltalk I've been able > to check: it does not mean the same thing any more and cannot be used the > same ways. > > The "classic" semantics is that a Date represents a cultural item, a day > in the proleptic Gregorian calendar, without reference to any particular > locality. For example, my most recent birthday was 2018-10-11, and it > would have been the same *date* but not the same *timespan* no matter > where I was in the world. The USA celebrated President's day on > 2018-02-19 this year, and it was the same *date* in every state, but > by no means the same *timespan*. > > Now, granting the utility of a class to represent the timespan associated > with a date in a given timezone, the obvious way to introduce it would > have been to introduce a new DateInZone class. Sadly, in Squeak the > Date class was changed incompatibly to take that role, with nothing left > to do what Date usefully did (and still does elsewhere). > > So now we have the problem that the original poster wanted to do > something perfectly sensible that works in nearly every other Smalltalk > and used to work in Squeak, but it doesn't work in Pharo. > > In this situation, I'd be strongly inclined to port say GNU Smalltalk's > Date class, renaming it to CompatibleDate, add a global variable > DateInZone, and add methods > CompatibleDate>>inZone: > DateInZone>>sansZone Date's current implementation and its implications has been the subject of many discussions before, it won't be the last. Both the simple, abstract calendar date as well as the more complex date in a timezone with a concrete timespan are useful. Using #translateToUTC and other techniques, you can make all your dates UTC based and be very close to the simple abstract calendar date. IMHO, what we need is to move away from TZ offsets towards real TZ identifiers (as in the Olson DB). So not +02:00 but Europe/Brussels. Next we need chronology objects with/without TZ info (or maybe the without case can just be UTC). But it is also very important to acknowledge the limitations of the objects without TZ info, because this fallback on current TZ is way too brittle. Your simple old school calendar Date cannot be asked for its start or stop or whether it includes a specific time, since all these need a TZ. The point about Date serialisation in the STON thread is illustrative here. The round trip of 1/1/2000 between my image, to some external representation without TZ, to your image will not be the same thing if we use different TZs. Given DST, the dates will even change by the season on the same machine. Not being aware of this complexity or hiding it will eventually lead to problems and bugs. > On Wed, 17 Oct 2018 at 09:44, Sven Van Caekenberghe <[hidden email]> wrote: > > > > On 16 Oct 2018, at 22:27, Alistair Grant <[hidden email]> wrote: > > > > Hi Petr, > > > > On Tue, 16 Oct 2018 at 21:25, Petr Fischer via Pharo-users > > <[hidden email]> wrote: > >> > >> My problem - use Dates as Dictionary keys - shortly: > >> > >> d1 := Date today translateToUTC. > >> d2 := Date today. > >> > >> d1 = d2. (true!) > > > > Which timezone are you in? > > > > CEDT (UTC+0200) gives false for this. > > > > Date is implemented primarily as a timespan, so days in different > > timezones are considered different. If you do: > > > > | d1 d2 | > > > > d1 := Date today translateTo: (TimeZone abbreviated: 'UTC') offset. > > d2 := Date today translateTo: (TimeZone abbreviated: 'EST') offset. > > > > { d1 = d2. d1 equals: d2 } > > > > > > You can see the difference. > > > > Of course, this doesn't help with using Date as a key in a dictionary. > > Probably your best option is to look at Sven's excellent ZTimezone > > package (although I haven't tested it in this scenario). > > > > I can't find the repository right now (I think Sven moved it to github). Sven? > > It is called ZTimestamp and it lives in various places, for example: https://github.com/svenvc/ztimestamp > > > Cheers, > > Alistair > > > > > > > >> d := Dictionary new. > >> d at: d1 put: 1. > >> > >> d at: d1. (ok) > >> d at: d2. (bad - key not found) > >> > >> --- > >> > >> pf > >> > > > > |
In reply to this post by Richard O'Keefe
Maybe this happened with Squeak version 3.7?
http://wiki.squeak.org/squeak/1871 --Hannes On 10/17/18, Richard O'Keefe <[hidden email]> wrote: > There is an elephant in the room. Historically and in Smalltalks such as > GNU Smalltalk, Smalltalk/X, my Smalltalk->C system, VisualAge Smalltalk, > and VisualWOrks, a Date is *not* a TimeSpan and is *not* associated with > a time zone or a zone offset. It's generally a direct subclass of > Magnitude. And this was originally true in Squeak as well. I just had a > look at SqueakV2.source to verify that. > > At some point subsequent to the 2.x series, Squeak made an incompatible > and to me incomprehensible change, with the result that "Date" in today's > Squeak and Pharo is incompatible with every other Smalltalk I've been able > to check: it does not mean the same thing any more and cannot be used the > same ways. > > The "classic" semantics is that a Date represents a cultural item, a day > in the proleptic Gregorian calendar, without reference to any particular > locality. For example, my most recent birthday was 2018-10-11, and it > would have been the same *date* but not the same *timespan* no matter > where I was in the world. The USA celebrated President's day on > 2018-02-19 this year, and it was the same *date* in every state, but > by no means the same *timespan*. > > Now, granting the utility of a class to represent the timespan associated > with a date in a given timezone, the obvious way to introduce it would > have been to introduce a new DateInZone class. Sadly, in Squeak the > Date class was changed incompatibly to take that role, with nothing left > to do what Date usefully did (and still does elsewhere). > > So now we have the problem that the original poster wanted to do > something perfectly sensible that works in nearly every other Smalltalk > and used to work in Squeak, but it doesn't work in Pharo. > > In this situation, I'd be strongly inclined to port say GNU Smalltalk's > Date class, renaming it to CompatibleDate, add a global variable > DateInZone, and add methods > CompatibleDate>>inZone: > DateInZone>>sansZone > > > > On Wed, 17 Oct 2018 at 09:44, Sven Van Caekenberghe <[hidden email]> wrote: > >> >> >> > On 16 Oct 2018, at 22:27, Alistair Grant <[hidden email]> wrote: >> > >> > Hi Petr, >> > >> > On Tue, 16 Oct 2018 at 21:25, Petr Fischer via Pharo-users >> > <[hidden email]> wrote: >> >> >> >> My problem - use Dates as Dictionary keys - shortly: >> >> >> >> d1 := Date today translateToUTC. >> >> d2 := Date today. >> >> >> >> d1 = d2. (true!) >> > >> > Which timezone are you in? >> > >> > CEDT (UTC+0200) gives false for this. >> > >> > Date is implemented primarily as a timespan, so days in different >> > timezones are considered different. If you do: >> > >> > | d1 d2 | >> > >> > d1 := Date today translateTo: (TimeZone abbreviated: 'UTC') offset. >> > d2 := Date today translateTo: (TimeZone abbreviated: 'EST') offset. >> > >> > { d1 = d2. d1 equals: d2 } >> > >> > >> > You can see the difference. >> > >> > Of course, this doesn't help with using Date as a key in a dictionary. >> > Probably your best option is to look at Sven's excellent ZTimezone >> > package (although I haven't tested it in this scenario). >> > >> > I can't find the repository right now (I think Sven moved it to >> github). Sven? >> >> It is called ZTimestamp and it lives in various places, for example: >> https://github.com/svenvc/ztimestamp >> >> > Cheers, >> > Alistair >> > >> > >> > >> >> d := Dictionary new. >> >> d at: d1 put: 1. >> >> >> >> d at: d1. (ok) >> >> d at: d2. (bad - key not found) >> >> >> >> --- >> >> >> >> pf >> >> >> > >> >> >> > |
In reply to this post by alistairgrant
Hi,
On Tue, Oct 16, 2018 at 1:28 PM Alistair Grant <[hidden email]> wrote: Hi Petr, The base problem here is that the hash of the dates is not the same for dates that are equal - that should never happen. If you try d1 hash = d2 hash you should see that the hash's are different (Petr for sure; you for the cases where the offsets are different). When objects (especially fo the same class) are =, then their hash must be the same as well, or things break. -cbc |
Administrator
|
In reply to this post by Sven Van Caekenberghe-2
Sven Van Caekenberghe-2 wrote
>> the obvious way to introduce it would >> have been to introduce a new DateInZone class. Yes, that would have been nice. Especially since IMHO this is the more common, simple case, and least surprising to new users. I would assume by the time you're building international apps there is decent familiarization with the system. Sven Van Caekenberghe-2 wrote > Both the simple, abstract calendar date as well as the more complex date > in a timezone with a concrete timespan are useful. Agreed. The additional problem (besides incompatible/inconsistent naming) with the Squeak/Pharo implementation of option #2 is that they are buggy and incomplete. ----- Cheers, Sean -- Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
Cheers,
Sean |
In reply to this post by cbc
Chris,
That is not what I am seeing in Pharo 7: date1 := Date today. date2 := Date today translateToUTC. date1 = date2. "false" date1 hash = date2 hash. "false" dictionary := Dictionary new. dictionary at: date1 put: date1. dictionary at: date2 put: date2. (dictionary at: date1) = date1. "true" (dictionary at: date2) = date2. "true" dictionary. "a Dictionary(17 October 2018->17 October 2018 17 October 2018->17 October 2018 )" date1 offset. "0:02:00:00" date2 offset. "0:00:00:00" Both dates are different, but they are equal (an operation that ignores the offsets) date1 equals: date2. "true" Sven > On 17 Oct 2018, at 16:33, Chris Cunningham <[hidden email]> wrote: > > Hi, > > On Tue, Oct 16, 2018 at 1:28 PM Alistair Grant <[hidden email]> wrote: > Hi Petr, > > On Tue, 16 Oct 2018 at 21:25, Petr Fischer via Pharo-users > <[hidden email]> wrote: > > > > My problem - use Dates as Dictionary keys - shortly: > > > > d1 := Date today translateToUTC. > > d2 := Date today. > > > > d1 = d2. (true!) > > Of course, this doesn't help with using Date as a key in a dictionary. > Probably your best option is to look at Sven's excellent ZTimezone > package (although I haven't tested it in this scenario). > > The base problem here is that the hash of the dates is not the same for dates that are equal - that should never happen. If you try > d1 hash = d2 hash > you should see that the hash's are different (Petr for sure; you for the cases where the offsets are different). > > When objects (especially fo the same class) are =, then their hash must be the same as well, or things break. > > -cbc |
Free forum by Nabble | Edit this page |