The Inbox: Kernel-cmm.669.mcz

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

The Inbox: Kernel-cmm.669.mcz

commits-2
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 ===============

Item was changed:
  Timespan subclass: #Date
  instanceVariableNames: ''
  classVariableNames: ''
  poolDictionaries: 'ChronologyConstants'
  category: 'Kernel-Chronology'!
 
+ !Date commentStamp: 'cmm 2/3/2012 17:30' prior: 0!
- !Date commentStamp: '<historical>' prior: 0!
  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.
+ !
- Their default creation assumes a start of midnight in the local time zone.!

Item was changed:
  ----- Method: Date class>>julianDayNumber: (in category 'squeak protocol') -----
+ julianDayNumber: aJulianDayNumber
+ ^ self starting:
+ (DateAndTime
+ julianDayNumber: aJulianDayNumber
+ offset: self defaultOffset)!
- julianDayNumber: aJulianDayNumber
-
- ^ self starting: (DateAndTime julianDayNumber: aJulianDayNumber)!

Item was changed:
  ----- Method: Date class>>starting: (in category 'squeak protocol') -----
  starting: aDateAndTime
+ ^ self
- ^ super
  starting: aDateAndTime midnight
  duration: Duration oneDay!

Item was changed:
  ----- Method: Date class>>year:day: (in category 'squeak protocol') -----
+ year: year day: dayOfYear
+ ^ self starting:
+ (DateAndTime
+ year: year
+ day: dayOfYear
+ hour: 0
+ minute: 0
+ second: 0
+ offset: self defaultOffset)!
- year: year day: dayOfYear
-
- ^ self starting: (DateAndTime year: year day: dayOfYear)
- !

Item was changed:
  ----- Method: Date class>>year:month:day: (in category 'squeak protocol') -----
+ year: year month: month day: day
+ ^ self starting:
+ (DateAndTime
+ year: year
+ month: month
+ day: day
+ hour: 0
+ minute: 0
+ second: 0
+ offset: self defaultOffset)!
- year: year month: month day: day
-
- ^ self starting: (DateAndTime year: year month: month day: day)!

Item was changed:
  ----- Method: DateAndTime class>>julianDayNumber: (in category 'squeak protocol') -----
+ julianDayNumber: anInteger
+ ^ self
+ julianDayNumber: anInteger
+ offset: self localOffset!
- julianDayNumber: aJulianDayNumber
-
- ^ self basicNew
- ticks: aJulianDayNumber days ticks offset: self localOffset;
- yourself!

Item was added:
+ ----- Method: DateAndTime class>>julianDayNumber:offset: (in category 'squeak protocol') -----
+ julianDayNumber: anInteger offset: aDuration
+ ^ self basicNew
+ ticks: anInteger days ticks
+ offset: aDuration ;
+ yourself!

Item was changed:
  ----- Method: DateAndTime class>>now (in category 'ansi protocol') -----
  now
+ ^ self nowWithOffset: self localOffset!
- | nanoTicks msm |
-
- nanoTicks := (msm := self milliSecondsSinceMidnight) * 1000000.
-
- (LastTick < nanoTicks) ifTrue: [
- LastTick := nanoTicks.
- ^ self todayAtMilliSeconds: msm].
-
- LastTickSemaphore critical: [
- LastTick :=  LastTick + 1.
- ^ self todayAtNanoSeconds: LastTick]
-
- "
- [ 10000 timesRepeat: [ self now. ] ] timeToRun / 10000.0 .
-
- If calls to DateAndTime-c-#now are within a single millisecond the semaphore code
- to ensure that (self now <= self now) slows things down considerably by a factor of about 20.
-
- The actual speed of a single call to DateAndTime-now in milliseconds is
- demonstrated by the unguarded method below.
-
- [ 100000 timesRepeat: [ self todayAtMilliSeconds: (self milliSecondsSinceMidnight) ] ] timeToRun / 100000.0 .  0.00494 0.00481 0.00492 0.00495
-  
- "!

Item was added:
+ ----- Method: DateAndTime class>>nowWithOffset: (in category 'squeak protocol') -----
+ nowWithOffset: aDuration
+ | nanoTicks msm |
+
+ nanoTicks := (msm := self milliSecondsSinceMidnight) * 1000000.
+
+ (LastTick < nanoTicks) ifTrue: [
+ LastTick := nanoTicks.
+ ^ self todayAtMilliSeconds: msm offset: aDuration].
+
+ LastTickSemaphore critical: [
+ LastTick :=  LastTick + 1.
+ ^ self todayAtNanoSeconds: LastTick offset: aDuration]
+
+ "
+ [ 10000 timesRepeat: [ self now. ] ] timeToRun / 10000.0 .
+
+ If calls to DateAndTime-c-#now are within a single millisecond the semaphore code
+ to ensure that (self now <= self now) slows things down considerably by a factor of about 20.
+
+ The actual speed of a single call to DateAndTime-now in milliseconds is
+ demonstrated by the unguarded method below.
+
+ [ 100000 timesRepeat: [ self todayAtMilliSeconds: (self milliSecondsSinceMidnight) ] ] timeToRun / 100000.0 .  0.00494 0.00481 0.00492 0.00495
+  
+ "!

Item was changed:
  ----- Method: DateAndTime class>>todayAtMilliSeconds: (in category 'squeak protocol') -----
+ todayAtMilliSeconds: milliSecondsSinceMidnight
+ self deprecated: 'Use todayAtMilliSeconds:offset:.'.
+ ^ self
+ todayAtMilliSeconds: milliSecondsSinceMidnight
+ offset: self localOffset!
- todayAtMilliSeconds: milliSecondsSinceMidnight
-
- "This is usually only during system startup..."
- self waitForOffsets.
-
- ^ self basicNew
- setJdn: DaysSinceEpoch
- seconds: (milliSecondsSinceMidnight // 1000)
- nano: (milliSecondsSinceMidnight  \\ 1000 * 1000000  )
- offset: self localOffset
-
- "
- [ 100000 timesRepeat: [ self fromMilliSeconds: self milliSecondsSinceMidnight. ] ] timeToRun.
- "!

Item was added:
+ ----- Method: DateAndTime class>>todayAtMilliSeconds:offset: (in category 'squeak protocol') -----
+ todayAtMilliSeconds: milliSecondsSinceMidnight offset: aDuration
+
+ "This is usually only during system startup..."
+ self waitForOffsets.
+
+ ^ self basicNew
+ setJdn: DaysSinceEpoch
+ seconds: (milliSecondsSinceMidnight // 1000)
+ nano: (milliSecondsSinceMidnight  \\ 1000 * 1000000  )
+ offset: aDuration
+
+ "
+ [ 100000 timesRepeat: [ self fromMilliSeconds: self milliSecondsSinceMidnight. ] ] timeToRun.
+ "!

Item was changed:
  ----- Method: DateAndTime class>>todayAtNanoSeconds: (in category 'squeak protocol') -----
+ todayAtNanoSeconds: nanoSecondsSinceMidnight
+ self deprecated: 'Use todayAtNanoSeconds:offset:.'.
+ self
+ todayAtNanoSeconds: nanoSecondsSinceMidnight
+ offset: self localOffset!
- todayAtNanoSeconds: nanoSecondsSinceMidnight
-
- "This is usually only during system startup..."
- self waitForOffsets.
-
- ^ self basicNew
- setJdn: DaysSinceEpoch
- seconds: (nanoSecondsSinceMidnight // 1000000000)
- nano: (nanoSecondsSinceMidnight  \\ 1000000000  )
- offset: self localOffset
-  !

Item was added:
+ ----- Method: DateAndTime class>>todayAtNanoSeconds:offset: (in category 'squeak protocol') -----
+ todayAtNanoSeconds: nanoSecondsSinceMidnight offset: aDuration
+
+ "This is usually only during system startup..."
+ self waitForOffsets.
+
+ ^ self basicNew
+ setJdn: DaysSinceEpoch
+ seconds: (nanoSecondsSinceMidnight // 1000000000)
+ nano: (nanoSecondsSinceMidnight  \\ 1000000000  )
+ offset: self localOffset
+  !

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!

Item was changed:
  ----- Method: DateAndTime>>makeUTC (in category 'squeak protocol') -----
  makeUTC
+ "Make the receiver's timezone UTC."
- "Change the receiver's timezone to UTC. Like #asUTC, but modifies the receiver and is much faster."
  self primOffset: Duration zero!

Item was changed:
  ----- Method: DateAndTime>>midnight (in category 'squeak protocol') -----
  midnight
+ "Answer a DateAndTime starting at midnight of the same timezone offset as the receiver."
+ ^ self class basicNew
- "Answer a DateAndTime starting at midnight local time"
-
- ^self class basicNew
  setJdn: jdn
  seconds: 0
  nano: 0
+ offset: offset!
- offset: self class localOffset
- !

Item was changed:
  ----- Method: Month class>>month:year: (in category 'squeak protocol') -----
+ month: month year: year
- month: month year: year
  "Create a Month for the given <year> and <month>.
  <month> may be a number or a String with the
  name of the month. <year> should be with 4 digits."
+ ^ self starting:
+ (DateAndTime
+ year: year
+ month: month
+ day: 1
+ hour: 0
+ minute: 0
+ second: 0
+ offset: self defaultOffset)!
-
- ^ self starting: (DateAndTime year: year month: month day: 1)
- !

Item was changed:
  ----- Method: Month class>>starting:duration: (in category 'squeak protocol') -----
  starting: aDateAndTime duration: aDuration
  "Override - a each month has a defined duration"
  | start adjusted days |
  start := aDateAndTime asDateAndTime.
  adjusted := DateAndTime
+ year: start year
+ month: start month
+ day: 1
+ hour: 0
+ minute: 0
+ second: 0
+ offset: start offset.
+ days := self
+ daysInMonth: adjusted month
+ forYear: adjusted year.
- year: start year
- month: start month
- day: 1.
- days := self daysInMonth: adjusted month forYear: adjusted year.
  ^ super
  starting: adjusted
+ duration: (Duration days: days)!
- duration: (Duration days: days)
- !

Item was changed:
  Magnitude subclass: #Timespan
  instanceVariableNames: 'start duration'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'Kernel-Chronology'!
+ Timespan class
+ instanceVariableNames: 'defaultOffset'!
 
  !Timespan commentStamp: 'dtl 7/11/2009 16:35' prior: 0!
  I represent a duration starting on a specific DateAndTime.!
+ Timespan class
+ instanceVariableNames: 'defaultOffset'!

Item was changed:
  ----- Method: Timespan class>>current (in category 'squeak protocol') -----
  current
+ ^ self starting: (DateAndTime nowWithOffset: self defaultOffset)!
-
-
- ^ self starting: DateAndTime now!

Item was added:
+ ----- Method: Timespan class>>defaultOffset (in category 'configuring') -----
+ defaultOffset
+ ^ defaultOffset!

Item was added:
+ ----- Method: Timespan class>>globalize (in category 'configuring') -----
+ globalize
+ "By default, Timespans will be created with a local timezone's offset."
+ defaultOffset := Duration zero!

Item was added:
+ ----- Method: Timespan class>>initialize (in category 'initialize-release') -----
+ initialize
+ self globalize!

Item was added:
+ ----- Method: Timespan class>>localize (in category 'configuring') -----
+ localize
+ "By default, Timespans will be created with a local timezone's offset."
+ defaultOffset := DateAndTime localOffset!

Item was changed:
  ----- Method: Timespan class>>new (in category 'squeak protocol') -----
  new
  "Answer a Timespan starting on the Squeak epoch: 1 January 1901"
+ ^ self starting: (DateAndTime new offset: self defaultOffset)!
-
- ^ self starting: DateAndTime new
- !

Item was changed:
  ----- Method: Year class>>year: (in category 'squeak protocol') -----
+ year: aYear
+ ^ self starting:
+ (DateAndTime
+ year: aYear
+ month: 1
+ day: 1
+ hour: 0
+ minute: 0
+ second: 0
+ offset: self defaultOffset)!
- year: aYear
-
- ^ self starting: (DateAndTime year: aYear month: 1 day: 1).!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

Nicolas Cellier
2012/2/4  <[hidden email]>:

> 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

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

Nicolas Cellier
In reply to this post by commits-2
2012/2/4  <[hidden email]>:

> 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 ===============
>
> Item was changed:
>  ----- Method: DateAndTime>>midnight (in category 'squeak protocol') -----
>  midnight
> +       "Answer a DateAndTime starting at midnight of the same timezone offset as the receiver."
> +       ^ self class basicNew
> -       "Answer a DateAndTime starting at midnight local time"
> -
> -       ^self class basicNew
>                setJdn: jdn
>                seconds: 0
>                nano: 0
> +               offset: offset!
> -               offset: self class localOffset
> - !
>

I like this one because

| dateAndTime |
dateAndTime := DateAndTime year: 2012 month: 1 day: 1 hour: 1 minute:
1 second: 1 offset: 10 hours.
self assert: (dateAndTime asDate includes: dateAndTime)

will succeed whatever your local time zone...

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

David T. Lewis
In reply to this post by Nicolas Cellier
On Sun, Feb 05, 2012 at 10:46:42PM +0100, Nicolas Cellier wrote:

> 2012/2/4  <[hidden email]>:
> > 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


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

Nicolas Cellier
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 -
current_local_time_offset_in_seconds_to_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
#milliSecondsSinceMidnight)
- 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
Array
    with: julianDayNumberInOperatingSystemLocalTime
    with: secondsSinceMidnightLocalTime "Wall clock time"
    with: subSecondsFraction
    with: localTimeOffset

If we want, we could have a second primitive for UTC, but this is redundant:
Array
    with: julianDayNumberUTC
    with: secondsSinceMidnightUTC
    with: subSecondsFraction

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.

Nicolas

2012/2/6 David T. Lewis <[hidden email]>:

> On Sun, Feb 05, 2012 at 10:46:42PM +0100, Nicolas Cellier wrote:
>> 2012/2/4  <[hidden email]>:
>> > 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
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

David T. Lewis
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 -
> current_local_time_offset_in_seconds_to_utc
>
> So the image must reflect this...

Yes.


> 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
> #milliSecondsSinceMidnight)
> - 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
> Array
>     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:
> Array
>     with: julianDayNumberUTC
>     with: secondsSinceMidnightUTC
>     with: subSecondsFraction

A suitable primitive is currently implemented in the standard interpreter VM:

primitiveUtcWithOffset
        "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:

primUtcWithOffset
        "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."

        "Time primUtcWithOffset"

        <primitive: 'primitiveUtcWithOffset'>

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
do it.


> 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".


>
> Nicolas
>
> 2012/2/6 David T. Lewis <[hidden email]>:
> > On Sun, Feb 05, 2012 at 10:46:42PM +0100, Nicolas Cellier wrote:
> >> 2012/2/4 ?<[hidden email]>:
> >> > 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
> >
> >

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

Nicolas Cellier
2012/2/6 David T. Lewis <[hidden email]>:

> 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 -
>> current_local_time_offset_in_seconds_to_utc
>>
>> So the image must reflect this...
>
> Yes.
>
>
>> 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
>> #milliSecondsSinceMidnight)
>> - 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
>> Array
>>     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.
>

No, if the primitive also fill the localOffset, then you'll get twice
the same wallClockTime, but with a different localOffset.
In this case, conversion to UTC is trivial.

>>
>> If we want, we could have a second primitive for UTC, but this is redundant:
>> Array
>>     with: julianDayNumberUTC
>>     with: secondsSinceMidnightUTC
>>     with: subSecondsFraction
>
> A suitable primitive is currently implemented in the standard interpreter VM:
>
> primitiveUtcWithOffset
>        "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:
>
> primUtcWithOffset
>        "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."
>
>        "Time primUtcWithOffset"
>
>        <primitive: 'primitiveUtcWithOffset'>
>
> 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 don't know. The julianDayNumber sounds like assembler to me ;)
       
        p := (monthIndex - 14) quo: 12.
        q := year + 4800 + p.
        r := monthIndex - 2 - (12 * p).
        s := (year + 4900 + p) quo: 100.

        julianDayNumber :=
  ( (1461 * q) quo: 4 ) +
                        ( (367 * r) quo: 12 ) -
  ( (3 * s) quo: 4 ) +
  ( day - 32075 ).

Which date would overflow? Not that soon I guess.

Also, I'm not sure that duplicating the time zone and DST handling in
the image is a good idea.
What advantage over OS would this provide?

Nicolas

> 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
> do it.
>
>
>> 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".
>
>

SNIP

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

David T. Lewis
On Mon, Feb 06, 2012 at 02:59:03PM +0100, Nicolas Cellier wrote:

> 2012/2/6 David T. Lewis <[hidden email]>:
> >
> > 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.
> >
>
> No, if the primitive also fill the localOffset, then you'll get twice
> the same wallClockTime, but with a different localOffset.
> In this case, conversion to UTC is trivial.

Apologies, you are right of course.

> > 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 don't know. The julianDayNumber sounds like assembler to me ;)
>
> p := (monthIndex - 14) quo: 12.
> q := year + 4800 + p.
> r := monthIndex - 2 - (12 * p).
> s := (year + 4900 + p) quo: 100.
>
> julianDayNumber :=
>   ( (1461 * q) quo: 4 ) +
> ( (367 * r) quo: 12 ) -
>   ( (3 * s) quo: 4 ) +
>   ( day - 32075 ).
>
> Which date would overflow? Not that soon I guess.
>
> Also, I'm not sure that duplicating the time zone and DST handling in
> the image is a good idea.
> What advantage over OS would this provide?

If you do it in the image you can get it done right now, and if you
make a mistake you can fix it. If you do it in the VM, you will wait
for everyone involved to come to agreement, implement the code, and
distribute supported VMs.

As far as time zone and DST handling, you cannot realistically do
this in the VM except for the specific case of reporting the current
time, which involves nothing more than reporting the offset from UTC
in the current time zone at the current time. If the platform is
not able to provide this support, then you just report an offset
of zero.

Dave


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

espin

For leap seconds and how they are (mis)handled by the different OSs/distros have a look at http://queue.acm.org/detail.cfm?id=1967009

On Feb 6, 2012 3:16 PM, "David T. Lewis" <[hidden email]> wrote:
On Mon, Feb 06, 2012 at 02:59:03PM +0100, Nicolas Cellier wrote:
> 2012/2/6 David T. Lewis <[hidden email]>:
> >
> > 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.
> >
>
> No, if the primitive also fill the localOffset, then you'll get twice
> the same wallClockTime, but with a different localOffset.
> In this case, conversion to UTC is trivial.

Apologies, you are right of course.

> > 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 don't know. The julianDayNumber sounds like assembler to me ;)
>
>       p := (monthIndex - 14) quo: 12.
>       q := year + 4800 + p.
>       r := monthIndex - 2 - (12 * p).
>       s := (year + 4900 + p) quo: 100.
>
>       julianDayNumber :=
>               ( (1461 * q) quo: 4 ) +
>                       ( (367 * r) quo: 12 ) -
>                               ( (3 * s) quo: 4 ) +
>                                       ( day - 32075 ).
>
> Which date would overflow? Not that soon I guess.
>
> Also, I'm not sure that duplicating the time zone and DST handling in
> the image is a good idea.
> What advantage over OS would this provide?

If you do it in the image you can get it done right now, and if you
make a mistake you can fix it. If you do it in the VM, you will wait
for everyone involved to come to agreement, implement the code, and
distribute supported VMs.

As far as time zone and DST handling, you cannot realistically do
this in the VM except for the specific case of reporting the current
time, which involves nothing more than reporting the offset from UTC
in the current time zone at the current time. If the platform is
not able to provide this support, then you just report an offset
of zero.

Dave




Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

Nicolas Cellier
Thanks Enrico for this instructive and funny article.
I really doubt that so many airplanes are driven by NTP, except maybe
your home simulator, and even less so any TCAS.
And I agree with first comment of this post, if leap second would be
handled just like another localOffset, coding would be much much
simpler, because it is already supposed to deal with DST. Then OS
vendors would just have to routinely update the offset tables, like
they do when some countries change the law (the main reason why I'm
not fond of duplicating this administration in image).
Until nuclear plants are driven by Squeak and NTP, I suggest to not
bother, a pause of 1 second is just a medium garbage collect anyway ;)
One last, thing, isn't it a clock synchronization problem that made
Einstein invent his theory of relativity? Funny that I don't see a
word about it, either every one consider the problem is solved, or
they just forgot about it. Good luck though for the definition of
inter-galactic "true universal time" found in the wish list among
comments ;) Especially a coordinated one, no matter some galaxy may
suffer from a few million years delay before they are informed of any
leap adjustment bound to latest estimation of universe spreading ;)

Nicolas

2012/2/6 Enrico Spinielli <[hidden email]>:
> For leap seconds and how they are (mis)handled by the different OSs/distros
> have a look at http://queue.acm.org/detail.cfm?id=1967009
>

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-cmm.669.mcz

David T. Lewis

On Tue, Feb 07, 2012 at 12:43:11AM +0100, Nicolas Cellier wrote:
>
> 2012/2/6 Enrico Spinielli <[hidden email]>:
> > For leap seconds and how they are (mis)handled by the different OSs/distros
> > have a look at http://queue.acm.org/detail.cfm?id=1967009
> >

Enrico,

Thanks for this link, it is a good read.

> Thanks Enrico for this instructive and funny article.
> I really doubt that so many airplanes are driven by NTP, except maybe
> your home simulator, and even less so any TCAS.
> And I agree with first comment of this post, if leap second would be
> handled just like another localOffset, coding would be much much
> simpler, because it is already supposed to deal with DST. Then OS
> vendors would just have to routinely update the offset tables, like
> they do when some countries change the law (the main reason why I'm
> not fond of duplicating this administration in image).
> Until nuclear plants are driven by Squeak and NTP, I suggest to not
> bother, a pause of 1 second is just a medium garbage collect anyway ;)
> One last, thing, isn't it a clock synchronization problem that made
> Einstein invent his theory of relativity? Funny that I don't see a
> word about it, either every one consider the problem is solved, or
> they just forgot about it. Good luck though for the definition of
> inter-galactic "true universal time" found in the wish list among
> comments ;) Especially a coordinated one, no matter some galaxy may
> suffer from a few million years delay before they are informed of any
> leap adjustment bound to latest estimation of universe spreading ;)

Nicolas,

Funny you should bring that up. I also made a joke of it when I wrote
the class comment for PointInTime (in the TimeZoneDatabase package) many
years ago:

  "I am based on the naive assumption that time can be represented as
  a single continuum which may be experienced identically at different
  physical locations and velocities, and such that two observers in two
  different locations can identify a single PointInTime as a simultaneous
  event. These assumptions are not valid when relativity is taken into
  account, but are acceptable for use in Newtonian physics and Smalltalk."

;-)

I think that leap seconds are easier to understand when you can look
at them in Smalltalk. If you have TimeZoneDatabase loaded in your
image, try "TimeZoneDatabase systemDatabase explore". You will see
a leapSecondRuleSet that is shared by all time zones that make use
of leap second rules (because leap seconds apply to the rotation of
the earth as a whole, so the same rules apply everywhere). You can
look at the various time zone rule sets by looking into the timeZones
dictionary (which is a dictionary of dictionaries, patterned after
the directory structure of /usr/share/zoneinfo). Time zone names
like "right/America/Detroit" use the leap second rules, while the
"America/Detroit" time zone is exactly the same except that it does
not use the leap second rules (don't ask me why it is called "right",
I have no idea).

Dave