[squeak-dev] The Inbox: Kernel-cmm.669.mcz
David T. Lewis
lewis at mail.msen.com
Mon Feb 6 13:31:24 UTC 2012
On Mon, Feb 06, 2012 at 12:18:07PM +0100, Nicolas Cellier wrote:
> OK, I understand.
> The vm (primSecondsClock) is answering number of seconds since
> January 1, 1901 00h00 Local Time
> Or more exactly,
> seconds_ellapsed_since_January_1_1901_00h00_UTC -
> So the image must reflect this...
> I noticed that the vm has to answer a LargePositiveInteger (Time
> primSecondsClock class), which I find a bit suboptimal...
> I browsed all the DateAndTime now, secondsWhenClockTicks,
> initializeOffsets, milliSecondsSinceMidnight and found the code
> - complex (I particularly don't like MilliSecondOffset :=
> MilliSecondOffset + (SmallInteger maxVal // 2) + 1 in
> - optimistic or brittle (what guaranty against preemption by other
> process #secondsWhenClockTicks has ?)
> If we want the underlying operating system to handle time zone and DST for us,
> then it would be more convenient to have a vm primitive filling an
> with: julianDayNumberInOperatingSystemLocalTime
> with: secondsSinceMidnightLocalTime "Wall clock time"
> with: subSecondsFraction
> with: localTimeOffset
This still leaves us with the problem of converting from local time to UTC
in the image, which is problematic during a daylight savings time transition
(two values of the UTC seconds clock map to the same local seconds clock
value, which one is correct?). It is better to use UTC because translating
from UTC to local seconds is unambiguous.
> If we want, we could have a second primitive for UTC, but this is redundant:
> with: julianDayNumberUTC
> with: secondsSinceMidnightUTC
> with: subSecondsFraction
A suitable primitive is currently implemented in the standard interpreter VM:
"Answer an array with UTC microseconds since the Posix epoch and
the current seconds offset from GMT in the local time zone.
This is a named (not numbered) primitive in the null module (ie the VM)"
If you want to experiment with it, add the following method to the class side of Time:
"Invoke the primitive implemented in recent Squeak VMs.
Answer an array with UTC microseconds since the Posix epoch and
the current seconds offset from GMT in the local time zone."
I think it is best to leave the complexity of translating to julian
day, seconds, etc on the image side rather that put it in the VM, unless
there is a measurable performance advantage to putting it in the VM.
I'll note also that the primitiveUtcWithOffset approach was originally
proposed by Lex Spoon about ten years ago, and has been periodically
debated and discussed ever since. My view is that Lex's approach provides
the best overall balance of conceptual clarity (well defined and documented
on Wikipedia) and implementation (fast, easy to implement on any platform,
minimal logic required in the support code). If (and this is a big "if")
we are going to go to the trouble of changing the image to use UTC as
a basis rather than local time, then this approach is the right way to
> As for leap seconds, they seem rather impractical to me, because:
> - they exist for very few years
> - they are irregular and can only be represented in a sort of database
> - they are rather unpredictable
> IMHO, only astronomical apps would use such information.
I agree. For any reasonable use case, it is sufficient to let the operating
system decide whether or not to consider leap seconds when we ask the
VM for "seconds since the epoch".
> 2012/2/6 David T. Lewis <lewis at mail.msen.com>:
> > On Sun, Feb 05, 2012 at 10:46:42PM +0100, Nicolas Cellier wrote:
> >> 2012/2/4 ?<commits at source.squeak.org>:
> >> > A new version of Kernel was added to project The Inbox:
> >> > http://source.squeak.org/inbox/Kernel-cmm.669.mcz
> >> >
> >> > ==================== Summary ====================
> >> >
> >> > Name: Kernel-cmm.669
> >> > Author: cmm
> >> > Time: 3 February 2012, 5:55:11.175 pm
> >> > UUID: 5ddec343-01ad-4e76-b32c-299fac68ec09
> >> > Ancestors: Kernel-eem.668
> >> >
> >> > Introduced Timespan class>>defaultOffset. ?This is the offset that will be used for creation of all Timespans when an offset is not specified. ?When an offset is specified or involved in construction or calculation, the result is now produced in terms of the source offset.
> >> > ? ? ? ?For example, Date today now produces a globalized date by default. ?However, "Date starting: (DateAndTime year: 2004 month: 2 day: 29 hour: 13 minute: 33 second: 0 offset: 2 hours)" produces a Date.whose start is expressed in terms of UTC+2.
> >> > ? ? ? ?The default defaultOffset is Duration zero so that Squeak will have fast, globalized Dates out of the box. ?Globalized Dates are common for applications.
> >> > ? ? ? ?Legacy localized Dates can be obtained by evaluating "Date localize" so that, when an offset is not specified or otherwise involved in the input, the local offset will be used.
> >> >
> >> > =============== Diff against Kernel-eem.668 ===============
> >> >
> >> SNIP...
> >> >
> >> > Item was changed:
> >> > ?----- Method: DateAndTime>>asSeconds (in category 'smalltalk-80') -----
> >> > ?asSeconds
> >> > ? ? ? ?"Return the number of seconds since the Squeak epoch"
> >> > + ? ? ? ^ (self - (self class epoch offset: offset)) asSeconds!
> >> > -
> >> > - ? ? ? ^ (self - (self class epoch)) asSeconds!
> >> >
> >> OK, I see why you changed this one, just to preserve the fact that
> >> DateAndTime epoch is local time zone sensitive...
> >> But why was it so? Anyone has a good rationale?
> >> Nicolas
> > This is an important question, and I'll try to give some background
> > based on my best guess as to how things got into this condition.
> > Early Smalltalk was designed for small single-user machines, and was
> > intended to be used by individual people. It had date and time classes
> > that made sense for an person using a truly personal computer (before
> > "personal computers" ever existed). As long as time could be represented
> > in a simple way that made sense to someone using an individual Smalltalk
> > system in California, there was no need to worry about time zones,
> > daylight savings time, or any of that stuff. The date and time was
> > whatever the clock on the wall said it was, and that was sufficient.
> > Squeak emerged as a direct descendent of those systems, and was very
> > much a personal system. When the VM was developed, the system interface
> > for obtaining system time was designed to report seconds from the
> > Smalltalk epoch in the local time zone. This was simple, effective,
> > and appropriate for single user systems. It did not matter that the
> > Smalltalk epoch was an ambiguous thing (it is a different point in
> > time depending on what time zone you are in). It provided the simplest
> > and most direct mapping of system time (from the Mac, Windows, or
> > Unix operating system) into the time and date classes of early Squeak.
> > This worked very well for most people, who after all were using
> > Squeak as a personal system and had no reason to worry about how
> > their dates and times behave across time zones.
> > Fast forward to today: Squeak is used all around the world. It is
> > used for server applications and web apps in addition to personal
> > usage. And even individual users of Squeak are now using web applications
> > and Monticello and all sorts of things where time zones, time stamps,
> > and time durations begin to matter a lot more than they did in the
> > old days.
> > In this globally networked world, the choice of local time seconds
> > elapsed from an ambiguously define "epoch" for the VM becomes problematic.
> > Speaking in terms of Posix time (seconds since the Posix epoch), it is
> > very awkward to (for example) translate from Squeak time into Posix
> > seconds since the epoch, even though it would have been trivial for
> > most computers to report Posix seconds directly to Squeak. Consider
> > for example the case of Squeak time during a daylight savings transition,
> > in the one-hour period right after you set your clock back an hour
> > in the fall. If you imagine the Squeak seconds clock ticking along in
> > local time, it gets set back one hour and the same sequence of 3600
> > seconds gets repeated twice. If you combine this with the complexity
> > of calculating time durations correctly across time zones while accommodating
> > all the edge cases of daylight savings time and leap seconds, the whole
> > thing gets rather messy.
> > With the benefit of hindsight, it would be very nice if we could base
> > all time keeping in Squeak on a well-define time basis with a clearly
> > defined origin. In today's world, that means using the Posix epoch
> > and a time basis measured in seconds from that epoch. And it means
> > that local time as presented to the user in Squeak should be a
> > transformation from that time basis into local time. Ideally that
> > tranformation should be done using the rules in the Olson time zone
> > database (http://en.wikipedia.org/wiki/Tz_database) which is what
> > most modern computer systems and database use for this purpose.
> > For most people, it is acceptable to use the rudimentary TimeZone in
> > Squeak, which is basically just the current offset from UTC for the
> > current timezone. But this is a lot like the original simplified
> > time and date handing in early Smalltalk. It works fine for most
> > people most of the time, but it is just plain wrong if you need correct
> > duration calculations across time zones and daylight savings time
> > transitions.
> > (I am glossing over issues of leap seconds, which you can think of as
> > adjustments to the clock to keep earth rotational time in sync with
> > real atomic clock time. But the above issues are the same regardless
> > of whether leap second adjustments are considered.)
> > In summary, if you want to have time and dates and durations done
> > correctly, it would be best to make these fundamental changes:
> > 1) Use the Posix epoch as the origin of the time basis. Of course
> > any basis would work, but the Posix epoch is well documented and
> > unambiguously defined.
> > 2) Use Posix seconds for the underlying time basis reported from
> > the VM to the image, and have the image use this value (offset from
> > UTC as needed) to create new instances of times and dates. Thus
> > time reported by the VM is measured in seconds since the Posix epoch,
> > reported to whatever level of precision we want (microseconds).
> > 3) Have the VM report current offset from UTC for efficient creation
> > of new time instances in the image. Combine this with #1 above, so
> > that a primitive call reports current Posix time and offset from UTC
> > as a single operation.
> > 4) Assuming a primitive that implements the above, update Chronology
> > to use it.
> > 5) Update Chronology to use Olson time zone database rules to obtain
> > durations, such that durations are reported correctly even if daylight
> > savings time transitions are spanned, and even if the durations span
> > long periods of time and relate to different time zones.
> > Dave
More information about the Squeak-dev