> On Mar 23, 2016, at 6:55 PM, David T. Lewis <[hidden email]> wrote: > >> On Wed, Mar 23, 2016 at 05:50:19PM -0700, Eliot Miranda wrote: >>> On Wed, Mar 23, 2016 at 4:51 PM, David T. Lewis <[hidden email]> wrote: >>> >>>> On Wed, Mar 23, 2016 at 04:22:21PM -0700, Eliot Miranda wrote: >>>> >>>> Turns out this isn't needed for Cog. I have ioLocalSecondsOffset which >>>> answers a value determined at start-up and only changed >>>> via ioUpdateVMTimezone, which itself is controlled by >>>> primitiveUpdateTimezone, #243. So ioUTCMicroseconds is all that's needed >>>> to get at the clock and timezone atomically. >>> >>> If it is updated at start-up, then it's wrong. Think of daylight savings >>> time transitions. >> >> So update it automatically once a second or some such? > > Are you joking, or is that a serious question? Yes. I see two or three system calls in the code below. gettimeofday, one inside localtime and one inside gmtime. That's expensive. > > Confused, > Dave > > > /* implementation of ioUtcWithOffset(), defined in config.h to > /* override default definition in src/vm/interp.h > */ > sqInt sqUnixUtcWithOffset(sqLong *microSeconds, int *offset) > { > struct timeval timeval; > if (gettimeofday(&timeval, NULL) == -1) return -1; > time_t seconds= timeval.tv_sec; > suseconds_t usec= timeval.tv_usec; > *microSeconds= seconds * 1000000 + usec; > #if defined(HAVE_TM_GMTOFF) > *offset= localtime(&seconds)->tm_gmtoff; > #else > { > struct tm *local= localtime(&seconds); > struct tm *gmt= gmtime(&seconds); > int d= local->tm_yday - gmt->tm_yday; > int h= ((d < -1 ? 24 : 1 < d ? -24 : d * 24) + local->tm_hour - gmt->tm_hour); > int m= h * 60 + local->tm_min - gmt->tm_min; > *offset= m * 60; > } > #endif > return 0; > } > > > |
On Thu, Mar 24, 2016 at 10:05:17PM -0700, Eliot Miranda wrote:
> > > > On Mar 23, 2016, at 6:55 PM, David T. Lewis <[hidden email]> wrote: > > > >> On Wed, Mar 23, 2016 at 05:50:19PM -0700, Eliot Miranda wrote: > >>> On Wed, Mar 23, 2016 at 4:51 PM, David T. Lewis <[hidden email]> wrote: > >>> > >>>> On Wed, Mar 23, 2016 at 04:22:21PM -0700, Eliot Miranda wrote: > >>>> > >>>> Turns out this isn't needed for Cog. I have ioLocalSecondsOffset which > >>>> answers a value determined at start-up and only changed > >>>> via ioUpdateVMTimezone, which itself is controlled by > >>>> primitiveUpdateTimezone, #243. So ioUTCMicroseconds is all that's needed > >>>> to get at the clock and timezone atomically. > >>> > >>> If it is updated at start-up, then it's wrong. Think of daylight savings > >>> time transitions. > >> > >> So update it automatically once a second or some such? > > > > Are you joking, or is that a serious question? > > Yes. I see two or three system calls in the code below. gettimeofday, one inside localtime and one inside gmtime. That's expensive. > It's gettimeofday() and localtime(). The #else is fallback for older unix platforms. In any case, caching the value and updating it periodically does not sound like a good idea to me. Dave > > > > Confused, > > Dave > > > > > > /* implementation of ioUtcWithOffset(), defined in config.h to > > /* override default definition in src/vm/interp.h > > */ > > sqInt sqUnixUtcWithOffset(sqLong *microSeconds, int *offset) > > { > > struct timeval timeval; > > if (gettimeofday(&timeval, NULL) == -1) return -1; > > time_t seconds= timeval.tv_sec; > > suseconds_t usec= timeval.tv_usec; > > *microSeconds= seconds * 1000000 + usec; > > #if defined(HAVE_TM_GMTOFF) > > *offset= localtime(&seconds)->tm_gmtoff; > > #else > > { > > struct tm *local= localtime(&seconds); > > struct tm *gmt= gmtime(&seconds); > > int d= local->tm_yday - gmt->tm_yday; > > int h= ((d < -1 ? 24 : 1 < d ? -24 : d * 24) + local->tm_hour - gmt->tm_hour); > > int m= h * 60 + local->tm_min - gmt->tm_min; > > *offset= m * 60; > > } > > #endif > > return 0; > > } > > > > > > |
On Fri, Mar 25, 2016 at 8:51 AM, David T. Lewis <[hidden email]> wrote: On Thu, Mar 24, 2016 at 10:05:17PM -0700, Eliot Miranda wrote: As I said, two or three. In any case, caching the value and updating it periodically does not sound like a good idea to me. Why not? Why does the time zone need to be determined on every time call even though it only has a resolution of seconds? If including the timezone in every time call slows down accessing the time by, say, 33%, is it a good idea, when the VM can easily eliminate this overhead? | c | c := LargePositiveInteger. [1 to: 10000000 do: [:i| c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8]] timeToRun 884 [1 to: 10000000 do: [:i| Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock]] timeToRun 6412 6412 / 884.0 7.253393665158371 So the overhead of the system calls involved in accessing time are much greater than the costs of allocating and garbage collecting 64-bit large integer results; much larger. Dave
_,,,^..^,,,_ best, Eliot |
In reply to this post by David T. Lewis
On 25.03.2016, at 16:51, David T. Lewis <[hidden email]> wrote:
> > On Thu, Mar 24, 2016 at 10:05:17PM -0700, Eliot Miranda wrote: >> I see two or three system calls in the code below. gettimeofday, one inside localtime and one inside gmtime. That's expensive. >> > > It's gettimeofday() and localtime(). The #else is fallback for older unix platforms. > > In any case, caching the value and updating it periodically does not sound like a good idea to me. Well, it’s okay to cheat as long as you won’t get caught (says DI). Simply “once a second” is not good enough if we check the time 0.5 seconds after DST switch. If “once a second” was implemented as “once every wall-clock second”, IMHO that would be fine. So the test would have to be something like (prevUsecs // 1000000) ~= (nowUsecs // 1000000) ifTrue: [self updateOffsetFromUTC] Right? - Bert - smime.p7s (5K) Download Attachment |
On Fri, Mar 25, 2016 at 9:23 AM, Bert Freudenberg <[hidden email]> wrote: On 25.03.2016, at 16:51, David T. Lewis <[hidden email]> wrote: Excellent point. So the drift algorithm to provide an accurate clock can be extended to check the time zone whenever the new time is at a different second to the previous value. - Bert - _,,,^..^,,,_ best, Eliot |
On 25.03.2016, at 17:47, Eliot Miranda <[hidden email]> wrote:
Drifting makes this way more complicated I’d think … unless there is an OS function to convert the drifted UTC time into local? IF the VM time and system time differ, you can’t just ask the OS for the “now” local time.
- Bert - smime.p7s (5K) Download Attachment |
In reply to this post by Eliot Miranda-2
On Fri, Mar 25, 2016 at 09:22:09AM -0700, Eliot Miranda wrote:
> On Fri, Mar 25, 2016 at 8:51 AM, David T. Lewis <[hidden email]> wrote: > > > On Thu, Mar 24, 2016 at 10:05:17PM -0700, Eliot Miranda wrote: > > > > > > > > > > On Mar 23, 2016, at 6:55 PM, David T. Lewis <[hidden email]> > > wrote: > > > > > > > >> On Wed, Mar 23, 2016 at 05:50:19PM -0700, Eliot Miranda wrote: > > > >>> On Wed, Mar 23, 2016 at 4:51 PM, David T. Lewis <[hidden email]> > > wrote: > > > >>> > > > >>>> On Wed, Mar 23, 2016 at 04:22:21PM -0700, Eliot Miranda wrote: > > > >>>> > > > >>>> Turns out this isn't needed for Cog. I have ioLocalSecondsOffset > > which > > > >>>> answers a value determined at start-up and only changed > > > >>>> via ioUpdateVMTimezone, which itself is controlled by > > > >>>> primitiveUpdateTimezone, #243. So ioUTCMicroseconds is all that's > > needed > > > >>>> to get at the clock and timezone atomically. > > > >>> > > > >>> If it is updated at start-up, then it's wrong. Think of daylight > > savings > > > >>> time transitions. > > > >> > > > >> So update it automatically once a second or some such? > > > > > > > > Are you joking, or is that a serious question? > > > > > > Yes. I see two or three system calls in the code below. gettimeofday, > > one inside localtime and one inside gmtime. That's expensive. > > > > > > > It's gettimeofday() and localtime(). The #else is fallback for older unix > > platforms. > > > > As I said, two or three. > > In any case, caching the value and updating it periodically does not sound > > like a good idea to me. > > > > Why not? Why does the time zone need to be determined on every time call > even though it only has a resolution of seconds? If including the timezone > in every time call slows down accessing the time by, say, 33%, is it a good > idea, when the VM can easily eliminate this overhead? > > | c | > c := LargePositiveInteger. > [1 to: 10000000 do: [:i| c basicNew: 8. c basicNew: 8. c basicNew: 8. c > basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c basicNew: 8. c > basicNew: 8. c basicNew: 8]] timeToRun 884 > > > > [1 to: 10000000 do: [:i| Time utcMicrosecondClock. Time > utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. > Time utcMicrosecondClock. Time utcMicrosecondClock. Time > utcMicrosecondClock. Time utcMicrosecondClock. Time utcMicrosecondClock. > Time utcMicrosecondClock]] timeToRun 6412 > > > 6412 / 884.0 7.253393665158371 > > So the overhead of the system calls involved in accessing time are much > greater than the costs of allocating and garbage collecting 64-bit large > integer results; much larger. > I tested with the trunk ioUtcWithOffset(), interpreter VM, and calling the primitive with pre-allocated array to avoid garbage collection. I compared the primitive versus a hacked version with the offset value hard coded (equivalant to you suggestion of caching it). You're right, the "cached" version is almost 4 times faster. I still think that it is needless complexity. But yes it's faster. Dave |
In reply to this post by Bert Freudenberg
On Fri, Mar 25, 2016 at 10:08 AM, Bert Freudenberg <[hidden email]> wrote:
I wrote up the algorithm I propose; see http://forum.world.st/Time-millisecondClockValue-was-The-Trunk-Morphic-mt-1080-mcz-tt4877661.html#a4877918 It's not that complicated and extending it is straight-forward, given that the algorithm already maintains the last time computed. When I've time I'll post a revision. _,,,^..^,,,_ best, Eliot |
Terminology confusion. In your post "local time" means "wall clock utc". I meant "time in local time zone". But I see that there is indeed an OS function to convert a given UTC time to one in the local time zone. So yes, that sounds like a plan. - Bert - smime.p7s (8K) Download Attachment |
On Sat, Mar 26, 2016 at 4:30 AM, Bert Freudenberg <[hidden email]> wrote:
> > On 25 Mar 2016, at 18:49, Eliot Miranda <[hidden email]> wrote: > > > > On Fri, Mar 25, 2016 at 10:08 AM, Bert Freudenberg <[hidden email]> > wrote: >> >> On 25.03.2016, at 17:47, Eliot Miranda <[hidden email]> wrote: >> >> >> On Fri, Mar 25, 2016 at 9:23 AM, Bert Freudenberg <[hidden email]> >> wrote: >>> >>> Well, it’s okay to cheat as long as you won’t get caught (says DI). >>> >>> Simply “once a second” is not good enough if we check the time 0.5 >>> seconds after DST switch. >>> >>> If “once a second” was implemented as “once every wall-clock second”, >>> IMHO that would be fine. So the test would have to be something like >>> >>> (prevUsecs // 1000000) ~= (nowUsecs // 1000000) ifTrue: [self >>> updateOffsetFromUTC] >>> >>> Right? >> >> >> Excellent point. So the drift algorithm to provide an accurate clock can >> be extended to check the time zone whenever the new time is at a different >> second to the previous value. >> >> >> Drifting makes this way more complicated I’d think … unless there is an OS >> function to convert the drifted UTC time into local? IF the VM time and >> system time differ, you can’t just ask the OS for the “now” local time. > > > I wrote up the algorithm I propose; see > http://forum.world.st/Time-millisecondClockValue-was-The-Trunk-Morphic-mt-1080-mcz-tt4877661.html#a4877918 It would be useful if the 'now' instance variable in VMClock explicitly indicated in its name whether it was utcNow or localNow. Even reading the man pages for gettimeofday() and clock_gettime() its not clear to me which it is. I can only guess that in the face of changing timezones, its not a good idea to drift localNow, and better to drift utcNow and add a constant timeZoneOffset. > > It's not that complicated and extending it is straight-forward, given that > the algorithm already maintains the last time computed. When I've time I'll > post a revision. > > _,,,^..^,,,_ > best, Eliot > > > > Terminology confusion. In your post "local time" means "wall clock utc". I > meant "time in local time zone". > > But I see that there is indeed an OS function to convert a given UTC time to > one in the local time zone. So yes, that sounds like a plan. Microsoft, Linux & OSX all seem to agree that "Local-Time" is timezoned-wall-clock, and "System-Time" is utc-wall-clock. So maybe this is a worthwhile convention to continue? "The localtime() function converts the calendar time to broken-down time representation, expressed relative to the user's specified timezone." [1] "The system time is always kept in Coordinated Universal Time (UTC) and converted in applications to local time as needed. Local time is the actual time in your current time zone, taking into account daylight saving time (DST). [2] "GetLocalTime - This function retrieves the current local date and time." [3] "GetSystemTime - This function retrieves the current system date and time. The system time is expressed in UTC." [4] cheers -ben P.S. I also found [5] interesting [1] https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/localtime.3.html [2] https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/chap-Configuring_the_Date_and_Time.html [3] https://msdn.microsoft.com/en-us/library/ee487966.aspx [4] https://msdn.microsoft.com/en-us/library/ee488017.aspx [5] https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx |
In reply to this post by David T. Lewis
I would like to consider offering UTCDateAndTime for inclusion in trunk.
On 64-bit Spur, overall performance is almost twice that of the base Chronology package. In addition, the representation of DateAndTime as Posix time plus time zone offset is simpler and easier to test and understand. I cannot easily put this into the inbox, but loading the package into a trunk image is done as follows: (MCMcmUpdater updateMapNamed: 'update' repository: 'http://www.squeaksource.com/UTCDateAndTime') doUpdate: false. I have not modified any of the Chronology tests. After loading UTCDateAndTime into a trunk image, here are the tests that will fail, along with my explanation for the failures: DateAndTimeEpochTest>>testHash - DateAndTime>>hash works differently now. Test should be either updated or eliminated. DateAndTimeLeapTest>>testAsSeconds - Discussion required. I claim that #asSeconds can only make sense if it means elapsed seconds since the epoch. The prior implemention and the test are both wrong. DateAndTimeLeapTest>>testHash - DateAndTime>>hash works differently now. Test should be either updated or eliminated. DateAndTimeTest>>testPrecision - Discussion required. It is simply wrong to assume that two calls to DateAndTime class>>now will always answer different values, and it is even more wrong to fudge the clock accessors to make it appear to be doing this when it is not. Yes I know that certain database applications require distinct time stamps, but hacking the actual system clock is not the right thing to do. TimespanDoTest>>testDatesDo - Need to change the test setUp method. The original intent is to test date iteration using a time span begining with a UTC midnight. Test will pass if the start time is constructed accordingly. Note however that date iteration is suspect for durations starting at times other than midnight in the local time zone, so additional tests may be needed. TimespanDoTest>>testNext - Same issue as testDatesDo, fix the setUp method and the test will pass, but additional tests may be needed. The necessary #primitiveUtcWithOffset is present in all Cog/Spur/interpreter VMs. It is an optional named primitive (not numbered). If not present, the fallback code uses the Posix epoch for all new time values, resulting in a runnable image but with incorrect time stamps for new DateAndTime instances. Falling back to the original millisecond clock logic and primitives is possible, but it seemed to me to be an unnecessary complication so I got rid of it. Does anyone think that adding UTCDateAndTime to trunk is /not/ a good thing to do? Dave |
Hi David, thanks for proceeding with caution, clearly, this is a core
framework upon which everyone's Squeak everything depends. Some questions: > DateAndTimeLeapTest>>testAsSeconds > - Discussion required. I claim that #asSeconds can only make sense > if it means elapsed seconds since the epoch. The prior implemention > and the test are both wrong. Is there a context where the number of seconds since the epoch would ever "make sense" except to the software which needs to compare it to another result of #asSeconds? Why does it matter what number we start at? > DateAndTimeLeapTest>>testHash > - DateAndTime>>hash works differently now. Test should be either > updated or eliminated. > > DateAndTimeTest>>testPrecision > - Discussion required. It is simply wrong to assume that two calls > to DateAndTime class>>now will always answer different values, and > it is even more wrong to fudge the clock accessors to make it appear > to be doing this when it is not. Yes I know that certain database > applications require distinct time stamps, but hacking the actual > system clock is not the right thing to do. > > TimespanDoTest>>testDatesDo > - Need to change the test setUp method. The original intent is to test > date iteration using a time span begining with a UTC midnight. Test > will pass if the start time is constructed accordingly. Note however > that date iteration is suspect for durations starting at times other > than midnight in the local time zone, so additional tests may be needed. > > TimespanDoTest>>testNext > - Same issue as testDatesDo, fix the setUp method and the test will pass, > but additional tests may be needed. Can you clarify why the setUp method needs to be changed? What is the core difference between your framework and Chronology which makes this test not work as-is? I want to understand whether there are any compatibility issues to worry about other than the internal format and the #hash calculation? > The necessary #primitiveUtcWithOffset is present in all Cog/Spur/interpreter VMs. > It is an optional named primitive (not numbered). If not present, the fallback > code uses the Posix epoch for all new time values, resulting in a runnable image > but with incorrect time stamps for new DateAndTime instances. Falling back to the > original millisecond clock logic and primitives is possible, but it seemed to me > to be an unnecessary complication so I got rid of it. Wrong timestamps are a big deal. It would be better to have an unrunnable image than incorrect timestamps. The former makes a visible issue, the latter, an invisible, insidious one.. > Does anyone think that adding UTCDateAndTime to trunk is /not/ a good thing to do? Until we're sure its a good idea, it's /not/ a good thing to do. I would like to encourage us all to take the due time to really understand all the differences, and would ask someone to produce documentation (on the wiki) which explains exactly what developers need to do to, 1) update their application code, 2) update any persistent instances from Chronology of DateAndTime, etc. I think this will be a lot of work for me, but the reward will be faster dates and times, which is a good thing, thanks for pushing on this Dave. |
On Wed, Jun 22, 2016 at 06:07:00PM -0500, Chris Muller wrote:
> Hi David, thanks for proceeding with caution, clearly, this is a core > framework upon which everyone's Squeak everything depends. Some > questions: > > > DateAndTimeLeapTest>>testAsSeconds > > - Discussion required. I claim that #asSeconds can only make sense > > if it means elapsed seconds since the epoch. The prior implemention > > and the test are both wrong. > > Is there a context where the number of seconds since the epoch would > ever "make sense" except to the software which needs to compare it to > another result of #asSeconds? Why does it matter what number we start > at? > > > DateAndTimeLeapTest>>testHash > > - DateAndTime>>hash works differently now. Test should be either > > updated or eliminated. > > > > DateAndTimeTest>>testPrecision > > - Discussion required. It is simply wrong to assume that two calls > > to DateAndTime class>>now will always answer different values, and > > it is even more wrong to fudge the clock accessors to make it appear > > to be doing this when it is not. Yes I know that certain database > > applications require distinct time stamps, but hacking the actual > > system clock is not the right thing to do. > > > > TimespanDoTest>>testDatesDo > > - Need to change the test setUp method. The original intent is to test > > date iteration using a time span begining with a UTC midnight. Test > > will pass if the start time is constructed accordingly. Note however > > that date iteration is suspect for durations starting at times other > > than midnight in the local time zone, so additional tests may be needed. > > > > TimespanDoTest>>testNext > > - Same issue as testDatesDo, fix the setUp method and the test will pass, > > but additional tests may be needed. > > Can you clarify why the setUp method needs to be changed? What is the > core difference between your framework and Chronology which makes this > test not work as-is? I believe that the following would be consistent with the intent of the test, and will permit the tests to pass. The test is trying to interate dates through a time span of 91 days, and was written such that the time span would start on a midnight, such that it would iterate over 91 (not 92) dates. The change below accomplishes that in the #setUp. TimespanToTest>>setUp aDate := DateAndTime year: 2003 month: 01 day: 07 hour: 0 minute: 0 second: 0 offset: Duration zero. aDuration := Duration days: 91 hours: 0 minutes: 0 seconds: 0 nanoSeconds: 0. aTimespan := Timespan starting: aDate makeUTC duration: aDuration > > I want to understand whether there are any compatibility issues to > worry about other than the internal format and the #hash calculation? None that I can think of, but I have been looking at this much too long and I might easily be missing something. Let me know if you can think of anything, more eyeballs on this would be helpful. > > > The necessary #primitiveUtcWithOffset is present in all Cog/Spur/interpreter VMs. > > It is an optional named primitive (not numbered). If not present, the fallback > > code uses the Posix epoch for all new time values, resulting in a runnable image > > but with incorrect time stamps for new DateAndTime instances. Falling back to the > > original millisecond clock logic and primitives is possible, but it seemed to me > > to be an unnecessary complication so I got rid of it. > > Wrong timestamps are a big deal. It would be better to have an > unrunnable image than incorrect timestamps. The former makes a > visible issue, the latter, an invisible, insidious one.. I think the image must remain runnable, even if in a degraded mode. Otherwise you cannot fix it. I think (but am not sure) that someone would quickly notice if all new DateAndTime instances are 45 years old. We could restore the backward compatibility for running in fallback mode on the old millisecond primitives. I initially planned to keep that, but ended up concluding that it was just to much ugly old cruft to keep in the image. On the other hand, you may have noticed that I tend to be a big fan of backward compatibility, so you probably would not have a hard time convincing me if you think it is a good thing to do ;-) > > > Does anyone think that adding UTCDateAndTime to trunk is /not/ a good thing to do? > > Until we're sure its a good idea, it's /not/ a good thing to do. I > would like to encourage us all to take the due time to really > understand all the differences, and would ask someone to produce > documentation (on the wiki) which explains exactly what developers > need to do to, 1) update their application code, 2) update any > persistent instances from Chronology of DateAndTime, etc. > Agreed. And you have just confirmed my hypothesis that asking for positive feedback never works, while tossing out some flame bait can be tremendously effective. Maybe I'll try running for president next ;-) > I think this will be a lot of work for me, but the reward will be > faster dates and times, which is a good thing, thanks for pushing on > this Dave. I think that it actually will provide a good improvement. One thing I really do not know is how much of the improvement will be perceptible to the user in everyday activities. I am expecting speedups for things related to source code lookups, but I don't know if the low level speed improvements that I measure will translate into meaningful differences in real life. Do we have any benchmarks that might show if the DateAndTime speedups will result in improvements that would be noticed by an end user? Dave |
In reply to this post by Chris Muller-3
The class comment says:
Instances of Date are Timespans with duration of 1 day. Their default creation assumes a start of midnight of UTC to provide the fast, globalized Dates out of the box. The legacy behavior that creates Timezone-sensitive Dates can be used by sending #localizedDates. I no longer see #localizedDates in the image, so I think the comment needs an update. For reference, and earlier version of the class comment said this: Instances of Date are Timespans with duration of 1 day. Their default creation assumes a start of midnight in the local time zone. I am not sure what the comment should say, but I would be happy if it could better convey the intended meaning of "Date" in addition to the explanation about creating instances relative to UTC versus local time zone. My expectation would be that a Date is a Timespan with a start value set to midnight in some time zone. The start value is a DateAndTime, and the offset instance variable of that DateAndTime would reflect that time zone. I would therefore expect that a "globalized" Date is a special case of a Date that was created with the start of the Timespan at midnight UTC, regardless of the current local time zone. A "globalized" Date is no different from any other Date, it is simply a Date that was created with time zone UTC. Is that right? Dave |
Hi Dave, Dates created as positions by default is the definitely the
correct behavior. The original Date implementation inherited the abstraction from Timespan of a custom duration starting at a particular DateAndTime. While that is a fine for abstract Timespans, it turned out to be a bad idea for Dates, since the vast majority of the use of Dates are as positions, not spans. Check out the discussion surrounding Berts recent clarification of the implementation, where the timezone for Dates-as-positions is now set to nil, so the "localized" or "globalized" nomenclature can be removed from the comment. - Chris On Thu, Jun 23, 2016 at 8:05 AM, David T. Lewis <[hidden email]> wrote: > The class comment says: > > Instances of Date are Timespans with duration of 1 day. > > Their default creation assumes a start of midnight of UTC to provide the fast, globalized Dates out of the box. The legacy behavior that creates Timezone-sensitive Dates can be used by sending #localizedDates. > > > I no longer see #localizedDates in the image, so I think the comment needs an update. > > > For reference, and earlier version of the class comment said this: > > Instances of Date are Timespans with duration of 1 day. > Their default creation assumes a start of midnight in the local time zone. > > > I am not sure what the comment should say, but I would be happy if it could > better convey the intended meaning of "Date" in addition to the explanation > about creating instances relative to UTC versus local time zone. > > My expectation would be that a Date is a Timespan with a start value set to > midnight in some time zone. The start value is a DateAndTime, and the offset > instance variable of that DateAndTime would reflect that time zone. > > I would therefore expect that a "globalized" Date is a special case of a Date > that was created with the start of the Timespan at midnight UTC, regardless > of the current local time zone. A "globalized" Date is no different from any > other Date, it is simply a Date that was created with time zone UTC. > > Is that right? > > Dave > > |
Hi Chris,
I was really just trying to ask for a good class comment. The current comment contains an error, and I used that as an excuse for raising the question. I want to know the *meaning* of the Date class. And I would like the class comment to say what it means. The meaning seems to have changed considerably over the last ten or fifteen years as the implementations have changed, and I think that it would be helpful if the current definition could be stated as clearly as possible. On Sat, Jun 25, 2016 at 07:34:02PM -0500, Chris Muller wrote: > Hi Dave, Dates created as positions by default is the definitely the > correct behavior. The original Date implementation inherited the > abstraction from Timespan of a custom duration starting at a > particular DateAndTime. While that is a fine for abstract Timespans, > it turned out to be a bad idea for Dates, since the vast majority of > the use of Dates are as positions, not spans. I am not sure what is meant by "Dates as positions". When I first read this, I was thinking of "position relative to GMT" but on reading it again I realized that it probably means "position on a continuum of date values". Or maybe I am just completely confused (hence my plea for a good class comment). Despite my confusion, my own best guess at the current intended meaning of "Date" was in my original question below. A bit off topic, but is is worth asking: If we really want to model Date as a position on a continuum of date values, and if we think that the implementation of Date as a kind of Timespan is not right, then shouldn't we just consider going back to the earlier (Squeak 3.6 and earlier) implementation of Date as a Magnitude, rather than Date as a Timespan? Dave > > Check out the discussion surrounding Berts recent clarification of the > implementation, where the timezone for Dates-as-positions is now set > to nil, so the "localized" or "globalized" nomenclature can be removed > from the comment. > > - Chris > > > On Thu, Jun 23, 2016 at 8:05 AM, David T. Lewis <[hidden email]> wrote: > > The class comment says: > > > > Instances of Date are Timespans with duration of 1 day. > > > > Their default creation assumes a start of midnight of UTC to provide the fast, globalized Dates out of the box. The legacy behavior that creates Timezone-sensitive Dates can be used by sending #localizedDates. > > > > > > I no longer see #localizedDates in the image, so I think the comment needs an update. > > > > > > For reference, and earlier version of the class comment said this: > > > > Instances of Date are Timespans with duration of 1 day. > > Their default creation assumes a start of midnight in the local time zone. > > > > > > I am not sure what the comment should say, but I would be happy if it could > > better convey the intended meaning of "Date" in addition to the explanation > > about creating instances relative to UTC versus local time zone. > > > > My expectation would be that a Date is a Timespan with a start value set to > > midnight in some time zone. The start value is a DateAndTime, and the offset > > instance variable of that DateAndTime would reflect that time zone. > > > > I would therefore expect that a "globalized" Date is a special case of a Date > > that was created with the start of the Timespan at midnight UTC, regardless > > of the current local time zone. A "globalized" Date is no different from any > > other Date, it is simply a Date that was created with time zone UTC. > > > > Is that right? > > > > Dave > > > > |
Would the following work as a class comment for Date?
Date provides methods for dealing with calendar dates in different formats. Instances of Date are Timespans with duration of 1 day beginning at midnight. The start value of midnight, and possibly the duration of 1 day, depend on the time zone in which the Date is defined. In the most common usage, a Date is defined relative to UTC (time zone offset zero), and thus may be treated as a location independent calendar value. The current date, Date today, is assumed to be defined as a UTC date without consideration of local time zone. Dave On Sun, Jun 26, 2016 at 11:30:35PM -0400, David T. Lewis wrote: > Hi Chris, > > I was really just trying to ask for a good class comment. The current > comment contains an error, and I used that as an excuse for raising the > question. > > I want to know the *meaning* of the Date class. And I would like the > class comment to say what it means. The meaning seems to have changed > considerably over the last ten or fifteen years as the implementations > have changed, and I think that it would be helpful if the current > definition could be stated as clearly as possible. > > > On Sat, Jun 25, 2016 at 07:34:02PM -0500, Chris Muller wrote: > > Hi Dave, Dates created as positions by default is the definitely the > > correct behavior. The original Date implementation inherited the > > abstraction from Timespan of a custom duration starting at a > > particular DateAndTime. While that is a fine for abstract Timespans, > > it turned out to be a bad idea for Dates, since the vast majority of > > the use of Dates are as positions, not spans. > > I am not sure what is meant by "Dates as positions". When I first read > this, I was thinking of "position relative to GMT" but on reading it > again I realized that it probably means "position on a continuum of date > values". Or maybe I am just completely confused (hence my plea for a > good class comment). Despite my confusion, my own best guess at the > current intended meaning of "Date" was in my original question below. > > A bit off topic, but is is worth asking: > If we really want to model Date as a position on a continuum of date > values, and if we think that the implementation of Date as a kind of > Timespan is not right, then shouldn't we just consider going back to > the earlier (Squeak 3.6 and earlier) implementation of Date as a Magnitude, > rather than Date as a Timespan? > > Dave > > > > > Check out the discussion surrounding Berts recent clarification of the > > implementation, where the timezone for Dates-as-positions is now set > > to nil, so the "localized" or "globalized" nomenclature can be removed > > from the comment. > > > > - Chris > > > > > > On Thu, Jun 23, 2016 at 8:05 AM, David T. Lewis <[hidden email]> wrote: > > > The class comment says: > > > > > > Instances of Date are Timespans with duration of 1 day. > > > > > > Their default creation assumes a start of midnight of UTC to provide the fast, globalized Dates out of the box. The legacy behavior that creates Timezone-sensitive Dates can be used by sending #localizedDates. > > > > > > > > > I no longer see #localizedDates in the image, so I think the comment needs an update. > > > > > > > > > For reference, and earlier version of the class comment said this: > > > > > > Instances of Date are Timespans with duration of 1 day. > > > Their default creation assumes a start of midnight in the local time zone. > > > > > > > > > I am not sure what the comment should say, but I would be happy if it could > > > better convey the intended meaning of "Date" in addition to the explanation > > > about creating instances relative to UTC versus local time zone. > > > > > > My expectation would be that a Date is a Timespan with a start value set to > > > midnight in some time zone. The start value is a DateAndTime, and the offset > > > instance variable of that DateAndTime would reflect that time zone. > > > > > > I would therefore expect that a "globalized" Date is a special case of a Date > > > that was created with the start of the Timespan at midnight UTC, regardless > > > of the current local time zone. A "globalized" Date is no different from any > > > other Date, it is simply a Date that was created with time zone UTC. > > > > > > Is that right? > > > > > > Dave > > > > > > |
In reply to this post by David T. Lewis
On Mon, Jun 27, 2016 at 5:30 AM, David T. Lewis <[hidden email]> wrote: A bit off topic, but is is worth asking: I think this is a very relevant question. We may have to distinguish a Day from a Date. IMHO a birthday is a perfect example. It's defined by a day+month+year. If I was traveling I would celebrate the birthday in local time, so the generic "birthday" needs to compare equal to all the local dates independent of time zone. This is how Dates worked before we made them Timespans (because they had no time, and hence no time zone). And this is also how they worked after I added the "nil" offset hack (which ignores the timezone). But it's a hack, not a good design. I'm not entirely sure what a good design would look like that also does not break old code. - Bert - |
In reply to this post by David T. Lewis
Hi Dave,
Not that it matters too much to the Squeak world but a Date in VA Smalltalk is a Magnitude. I'm very glad you are trying to think all this data/time stuff through. A while ago (like ten years) VA Smalltalk went from keeping time as an integer number of seconds to keeping them as milliseconds. In and of itself that was fine but they changed #asSeconds from answering that number of seconds to answering a rounded number of milliseconds. This broke some of my code as it made some time values (when represented as seconds) look like a time in the future. IMHO rounding shouldn't be used unless it is needed just before a value is being displayed for humans. That wasn't the case here and although many if not most people agreed with me, I didn't discover the change until it had been in place for a long time and Instantiations was reluctant to fix it. Lou On Sun, 26 Jun 2016 23:30:35 -0400, "David T. Lewis" <[hidden email]> wrote: >Hi Chris, > >I was really just trying to ask for a good class comment. The current >comment contains an error, and I used that as an excuse for raising the >question. > >I want to know the *meaning* of the Date class. And I would like the >class comment to say what it means. The meaning seems to have changed >considerably over the last ten or fifteen years as the implementations >have changed, and I think that it would be helpful if the current >definition could be stated as clearly as possible. > > >On Sat, Jun 25, 2016 at 07:34:02PM -0500, Chris Muller wrote: >> Hi Dave, Dates created as positions by default is the definitely the >> correct behavior. The original Date implementation inherited the >> abstraction from Timespan of a custom duration starting at a >> particular DateAndTime. While that is a fine for abstract Timespans, >> it turned out to be a bad idea for Dates, since the vast majority of >> the use of Dates are as positions, not spans. > >I am not sure what is meant by "Dates as positions". When I first read >this, I was thinking of "position relative to GMT" but on reading it >again I realized that it probably means "position on a continuum of date >values". Or maybe I am just completely confused (hence my plea for a >good class comment). Despite my confusion, my own best guess at the >current intended meaning of "Date" was in my original question below. > >A bit off topic, but is is worth asking: >If we really want to model Date as a position on a continuum of date >values, and if we think that the implementation of Date as a kind of >Timespan is not right, then shouldn't we just consider going back to >the earlier (Squeak 3.6 and earlier) implementation of Date as a Magnitude, >rather than Date as a Timespan? > >Dave > >> >> Check out the discussion surrounding Berts recent clarification of the >> implementation, where the timezone for Dates-as-positions is now set >> to nil, so the "localized" or "globalized" nomenclature can be removed >> from the comment. >> >> - Chris >> >> >> On Thu, Jun 23, 2016 at 8:05 AM, David T. Lewis <[hidden email]> wrote: >> > The class comment says: >> > >> > Instances of Date are Timespans with duration of 1 day. >> > >> > Their default creation assumes a start of midnight of UTC to provide the fast, globalized Dates out of the box. The legacy behavior that creates Timezone-sensitive Dates can be used by sending #localizedDates. >> > >> > >> > I no longer see #localizedDates in the image, so I think the comment needs an update. >> > >> > >> > For reference, and earlier version of the class comment said this: >> > >> > Instances of Date are Timespans with duration of 1 day. >> > Their default creation assumes a start of midnight in the local time zone. >> > >> > >> > I am not sure what the comment should say, but I would be happy if it could >> > better convey the intended meaning of "Date" in addition to the explanation >> > about creating instances relative to UTC versus local time zone. >> > >> > My expectation would be that a Date is a Timespan with a start value set to >> > midnight in some time zone. The start value is a DateAndTime, and the offset >> > instance variable of that DateAndTime would reflect that time zone. >> > >> > I would therefore expect that a "globalized" Date is a special case of a Date >> > that was created with the start of the Timespan at midnight UTC, regardless >> > of the current local time zone. A "globalized" Date is no different from any >> > other Date, it is simply a Date that was created with time zone UTC. >> > >> > Is that right? >> > >> > Dave >> > >> > > Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon |
In reply to this post by Bert Freudenberg
So, Time and Dates are hard. When Date was a magnitude, it was easy. Now that it is a duration, it is occassionally wrong. Think about daylight savings time - at least one a year the day length is 25 hours, and once it is 23 hours (although in some places there are no Daylight Savings, so this isn't true, and in others, there are 2 switches, so it happens twice). Our current implementation doesn't take this into account - which is reasonable because it is hard to take this into account without a lot of work. If we want to keep Date as a timespan (with rough correctness), maybe we could also add in Day (as a magnitude) to work like the old Date? For what it is worth, I spend >80% of my time working with dates/timestamps, trying to turn them into Magnitudes for manipulations. The other 20%, I really enjoy them as timespans with locales since I deal with times from around the world. But the two uses are not quite easy to deal with - doable, just not quite intuitive. -cbc On Mon, Jun 27, 2016 at 3:41 AM, Bert Freudenberg <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |