The Inbox: Chronology-Core-dtl.59.mcz

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

The Inbox: Chronology-Core-dtl.59.mcz

commits-2
A new version of Chronology-Core was added to project The Inbox:
http://source.squeak.org/inbox/Chronology-Core-dtl.59.mcz

==================== Summary ====================

Name: Chronology-Core-dtl.59
Author: dtl
Time: 6 September 2020, 2:05:00.620796 pm
UUID: 99c99e87-ef4a-49ee-99eb-699c6c3dd65d
Ancestors: Chronology-Core-ul.58

Adopt simplifications from Cuis. Remove ChronologyConstants. Retain jmv author initials where possible. The shared pool is not required, it is simpler to use methods in the responsible classes.

For Squeak, OneDay is now a class variable in order to continue to allow Date instances to share a Duration. Cuis creates a new Duration for each Date. Class variable Zero is similarly defined.

=============== Diff against Chronology-Core-ul.58 ===============

Item was removed:
- SharedPool subclass: #ChronologyConstants
- instanceVariableNames: ''
- classVariableNames: 'DayNames DaysInMonth MicrosecondsInDay MonthNames NanosInMillisecond NanosInSecond OneDay SecondsInDay SecondsInHour SecondsInMinute SqueakEpoch Zero'
- poolDictionaries: ''
- category: 'Chronology-Core'!
-
- !ChronologyConstants commentStamp: 'brp 3/12/2004 14:34' prior: 0!
- ChronologyConstants is a SharedPool for the constants used by the Kernel-Chronology classes.!

Item was removed:
- ----- Method: ChronologyConstants class>>initialize (in category 'class initialization') -----
- initialize
- "ChronologyConstants initialize"
-
- SqueakEpoch := 2415386. "Julian day number of 1 Jan 1901"
- SecondsInDay := 86400.
- SecondsInHour := 3600.
- SecondsInMinute := 60.
- MicrosecondsInDay := 24 * 60 * 60 * 1000000.
- NanosInSecond := 10 raisedTo: 9.
- NanosInMillisecond := 10 raisedTo: 6.
- DayNames := #(Sunday Monday Tuesday Wednesday Thursday Friday Saturday).
-
- MonthNames := #( January February March April May June
- July August September October November December).
- DaysInMonth := #(31 28 31 30 31 30 31 31 30 31 30 31)!

Item was changed:
  Timespan subclass: #Date
  instanceVariableNames: ''
  classVariableNames: ''
+ poolDictionaries: ''
- poolDictionaries: 'ChronologyConstants'
  category: 'Chronology-Core'!
 
  !Date commentStamp: 'cmm 6/28/2016 21:36' prior: 0!
  Instances of Date are Timespans with duration of 1 day.  As with all Chronology Timespan sub-instances, Dates can be instantiated as position values which compare equally to any other instance of the same Date, irregardless of the timezone in which either is created.
 
  However, like the other Timespan subInstances, there are rare cases where it may be desirable to use instances of Date to represent a particular 1-day span of time at a particular locality on the globe.  All Timespans, including Dates, may specify a particular timezone offset for this purpose.!

Item was changed:
  ----- Method: Date class>>fromDays: (in category 'smalltalk-80') -----
  fromDays: dayCount
  "Days since 1 January 1901"
 
+ ^ self julianDayNumber: dayCount + Time squeakEpoch!
- ^ self julianDayNumber: dayCount + SqueakEpoch!

Item was changed:
  Magnitude subclass: #DateAndTime
  instanceVariableNames: 'utcMicroseconds localOffsetSeconds'
  classVariableNames: 'AutomaticTimezone ClockProvider InitializeFromPrimitive LocalTimeZone PosixEpochJulianDays'
+ poolDictionaries: ''
- poolDictionaries: 'ChronologyConstants'
  category: 'Chronology-Core'!
 
  !DateAndTime commentStamp: 'dtl 3/12/2016 10:32' prior: 0!
  I represent a point in UTC time as defined by ISO 8601. I have zero duration.
 
  My implementation uses variables utcMicroseconds and localOffsetSeconds. This represents time magnitude as elapsed microseconds since the Posix epoch, with localOffsetSeconds representing local offset from UTC. The magnitude is used for comparison and duration calculations, and the local offset is used for displaying this magnitude in the context of a local time zone.
 
  The implementation ignores leap seconds, which are adjustments made to maintain earth rotational clock time in synchronization with elapsed seconds.
 
  DateAndTime class>>now will use #primitiveUtcWithOffset to obtain current time in UTC microseconds with current local offset in seconds. The primitive provides an atomic query for UTC time and local offset as measured by the OS platform.  If primitiveUtcWithOffset is not available, the traditional implementation is used, which relies on a primitive for microseconds in the local time zone and derives UTC based on the TimeZone setting.
  !

Item was changed:
  ----- Method: DateAndTime class>>epochOffset (in category 'private') -----
  epochOffset
  "Elaspsed seconds from the Smalltalk epoch to the Posix epoch"
+ ^self daysFromSmalltalkEpochToPosixEpoch * Time secondsInDay!
- ^self daysFromSmalltalkEpochToPosixEpoch * SecondsInDay!

Item was changed:
  ----- Method: DateAndTime>>posixEpochJulianDays (in category 'initialize-release') -----
  posixEpochJulianDays
 
+ ^self class daysFromSmalltalkEpochToPosixEpoch + Time squeakEpoch!
- ^self class daysFromSmalltalkEpochToPosixEpoch + SqueakEpoch!

Item was changed:
  ----- Method: DateAndTime>>ticks:offset: (in category 'private') -----
  ticks: ticks offset: utcOffset
  "ticks is {julianDayNumber. secondCount. nanoSeconds}"
 
  | jdn s nanos normalizedTicks |
  normalizedTicks := ticks copy.
+ self normalize: 3 ticks: normalizedTicks base: Time nanosInSecond.
+ self normalize: 2 ticks: normalizedTicks base: Time secondsInDay.
- self normalize: 3 ticks: normalizedTicks base: NanosInSecond.
- self normalize: 2 ticks: normalizedTicks base: SecondsInDay.
 
  jdn := normalizedTicks at: 1.
  s := normalizedTicks at: 2.
  nanos := normalizedTicks at: 3.
  localOffsetSeconds := utcOffset ifNil: [0] ifNotNil: [utcOffset asSeconds].
  utcMicroseconds := self microsecondsFromDay: jdn seconds: s nanos: nanos offset: localOffsetSeconds.
  !

Item was changed:
  Magnitude subclass: #Duration
  instanceVariableNames: 'nanos seconds'
+ classVariableNames: 'OneDay Zero'
+ poolDictionaries: ''
- classVariableNames: ''
- poolDictionaries: 'ChronologyConstants'
  category: 'Chronology-Core'!
 
  !Duration commentStamp: 'dtl 7/11/2009 15:03' prior: 0!
  I represent a duration of time. I have nanosecond precision!

Item was changed:
  ----- Method: Duration class>>days: (in category 'squeak protocol') -----
  days: aNumber
 
+ ^ self seconds: aNumber * Time secondsInDay nanoSeconds: 0!
- ^ self seconds: aNumber * SecondsInDay nanoSeconds: 0!

Item was changed:
  ----- Method: Duration class>>days:hours:minutes:seconds:nanoSeconds: (in category 'squeak protocol') -----
  days: days hours: hours minutes: minutes seconds: seconds nanoSeconds: nanos
 
    ^self
  seconds: seconds
+ + (minutes * Time secondsInMinute)
+ + (hours * Time secondsInHour)
+ + (days * Time secondsInDay)
- + (minutes * SecondsInMinute)
- + (hours * SecondsInHour)
- + (days * SecondsInDay)
  nanoSeconds: nanos
  !

Item was changed:
  ----- Method: Duration class>>days:seconds: (in category 'ansi protocol') -----
  days: days seconds: seconds
 
+ ^ self basicNew seconds: days * Time secondsInDay + seconds nanoSeconds: 0!
- ^ self basicNew seconds: days * SecondsInDay + seconds nanoSeconds: 0
- !

Item was changed:
  ----- Method: Duration class>>hours: (in category 'squeak protocol') -----
  hours: aNumber
 
+ ^ self seconds: aNumber * Time secondsInHour nanoSeconds: 0!
- ^ self seconds: aNumber * SecondsInHour nanoSeconds: 0!

Item was changed:
  ----- Method: Duration class>>initialize (in category 'initialize-release') -----
  initialize
+ "Duration oneDay is used in Date creation, and is cached to allow
+ sharing the instance."
+ (OneDay := self days: 1) beReadOnlyObject.
+ "Duration zero is used in various comparisons and computations, and
+ is cached to allow reusing the instance."
+ (Zero := self seconds: 0 nanoSeconds: 0) beReadOnlyObject.
+ "The following recompilation is only needed during the transition
+ from pool variables to class variables."
+ self class
+   recompile: #oneDay;
+ recompile: #zero
+ !
- ChronologyConstants classPool
- at: #Zero
- put:
- (self basicNew
- seconds: 0
- nanoSeconds: 0) ;
- at: #OneDay
- put: 1 day!

Item was changed:
  ----- Method: Duration class>>milliSeconds: (in category 'squeak protocol') -----
  milliSeconds: milliCount
 
  ^self
  seconds: (milliCount quo: 1000)
+ nanoSeconds: (milliCount rem: 1000) * 1000000!
- nanoSeconds: (milliCount rem: 1000) * NanosInMillisecond!

Item was changed:
  ----- Method: Duration class>>minutes: (in category 'squeak protocol') -----
  minutes: aNumber
 
+ ^ self seconds: aNumber * Time secondsInMinute nanoSeconds: 0!
- ^ self seconds: aNumber * SecondsInMinute nanoSeconds: 0!

Item was changed:
  ----- Method: Duration class>>nanoSeconds: (in category 'squeak protocol') -----
  nanoSeconds: nanos
  "This method is slow. If you have nanos less than 10^6 you should use #seconds:nanoSeconds: instead."
 
  | quo |
+ quo _ nanos quo: Time nanosInSecond.
- quo := nanos quo: NanosInSecond.
  ^ self basicNew
  seconds: quo
+ nanoSeconds: nanos - (quo * Time nanosInSecond)!
- nanoSeconds: nanos - (quo * NanosInSecond)
- !

Item was changed:
  ----- Method: Duration class>>seconds:nanoSeconds: (in category 'squeak protocol') -----
  seconds: seconds nanoSeconds: nanos
 
  ^ self basicNew
  seconds: seconds truncated
+ nanoSeconds: seconds fractionPart * Time nanosInSecond + nanos!
- nanoSeconds: seconds fractionPart * NanosInSecond + nanos!

Item was changed:
  ----- Method: Duration>>asNanoSeconds (in category 'squeak protocol') -----
  asNanoSeconds
 
+ ^seconds * Time nanosInSecond + nanos!
- ^seconds * NanosInSecond + nanos!

Item was changed:
  ----- Method: Duration>>days (in category 'ansi protocol') -----
  days
  "Answer the number of days the receiver represents."
 
+ ^ seconds quo: Time secondsInDay!
- ^ seconds quo: SecondsInDay
- !

Item was changed:
  ----- Method: Duration>>hours (in category 'ansi protocol') -----
  hours
  "Answer the number of hours the receiver represents."
 
 
+ ^ (seconds rem: Time secondsInDay) quo: Time secondsInHour!
- ^ (seconds rem: SecondsInDay) quo: SecondsInHour!

Item was changed:
  ----- Method: Duration>>minutes (in category 'ansi protocol') -----
  minutes
-
  "Answer the number of minutes the receiver represents."
 
+ ^ (seconds rem: Time secondsInHour) quo: Time secondsInMinute!
-
- ^ (seconds rem: SecondsInHour) quo: SecondsInMinute!

Item was changed:
  ----- Method: Duration>>seconds (in category 'ansi protocol') -----
  seconds
  "Answer the number of seconds the receiver represents."
 
+ ^seconds rem: Time secondsInMinute!
- ^seconds rem: SecondsInMinute!

Item was changed:
  ----- Method: Duration>>seconds:nanoSeconds: (in category 'private') -----
  seconds: secondCount nanoSeconds: nanoCount
  "Private - only used by Duration class"
 
  seconds := secondCount.
  nanos := nanoCount rounded.
  "normalize if signs do not match"
  [ nanos < 0 and: [ seconds > 0 ] ]
  whileTrue: [ seconds := seconds - 1.
+ nanos := nanos + Time nanosInSecond ].
- nanos := nanos + NanosInSecond ].
  [ seconds < 0 and: [ nanos > 0 ] ]
  whileTrue: [ seconds := seconds + 1.
+ nanos := nanos - Time nanosInSecond ]
- nanos := nanos - NanosInSecond ]
 
  !

Item was changed:
  ----- Method: Duration>>ticks (in category 'private') -----
  ticks
  "Answer an array {days. seconds. nanoSeconds}. Used by DateAndTime and Time."
 
  | days |
  days := self days.
  ^ Array
  with: days
+ with: seconds - (days * Time secondsInDay)
- with: seconds - (days * SecondsInDay)
  with: nanos
  !

Item was changed:
  Timespan subclass: #Month
  instanceVariableNames: ''
  classVariableNames: ''
+ poolDictionaries: ''
- poolDictionaries: 'ChronologyConstants'
  category: 'Chronology-Core'!
 
  !Month commentStamp: 'cbr 7/28/2010 18:11' prior: 0!
  I represent a month.
 
  For example, to get the number of days this month, you can evaluate the following expression:
 
  Month current daysInMonth!

Item was added:
+ ----- Method: Month class>>daysInMonth (in category 'inquiries') -----
+ daysInMonth
+ ^#(31 28 31 30 31 30 31 31 30 31 30 31)!

Item was changed:
  ----- Method: Month class>>daysInMonth:forYear: (in category 'smalltalk-80') -----
  daysInMonth: indexOrName forYear: yearInteger
 
  | index |
  index := indexOrName isInteger
  ifTrue: [indexOrName]
  ifFalse: [self indexOfMonth: indexOrName].
+ ^ (self daysInMonth at: index)
- ^ (DaysInMonth at: index)
  + ((index = 2
  and: [Year isLeapYear: yearInteger])
  ifTrue: [1] ifFalse: [0])
  !

Item was changed:
  ----- Method: Month class>>indexOfMonth: (in category 'smalltalk-80') -----
  indexOfMonth: aMonthName
 
 
+ 1 to: 12 do: [ :i |  (aMonthName, '*' match: (self monthNames at: i)) ifTrue: [^i] ].
+ self error: aMonthName , ' is not a recognized month name'!
- 1 to: 12 do: [ :i |  (aMonthName, '*' match: (MonthNames at: i)) ifTrue: [^i] ].
- self error: aMonthName , ' is not a recognized month name'.!

Item was added:
+ ----- Method: Month class>>monthNames (in category 'inquiries') -----
+ monthNames
+ ^#(January February March April May June July August September October November December)!

Item was changed:
  ----- Method: Month class>>nameOfMonth: (in category 'smalltalk-80') -----
  nameOfMonth: anIndex
 
+ ^ self monthNames at: anIndex!
- ^ MonthNames at: anIndex.!

Item was changed:
  Magnitude subclass: #Time
  instanceVariableNames: 'seconds nanos'
  classVariableNames: 'ClockPolicy HighResClockTicksPerMillisecond LastClockTick UpdateVMTimeZoneCacheAt UseHighResClockForTiming'
+ poolDictionaries: ''
- poolDictionaries: 'ChronologyConstants'
  category: 'Chronology-Core'!
 
  !Time commentStamp: 'dew 10/23/2004 17:58' prior: 0!
  This represents a particular point in time during any given day.  For example, '5:19:45 pm'.
 
  If you need a point in time on a particular day, use DateAndTime.  If you need a duration of time, use Duration.
  !

Item was changed:
  ----- Method: Time class>>fromSeconds: (in category 'smalltalk-80') -----
  fromSeconds: secondCount
  "Answer an instance of me that is secondCount number of seconds since midnight."
 
  | integerSeconds nanos |
  integerSeconds := secondCount truncated.
  integerSeconds = secondCount
  ifTrue: [nanos := 0]
+ ifFalse: [nanos := (secondCount - integerSeconds * self nanosInSecond) asInteger].
- ifFalse: [nanos := (secondCount - integerSeconds * NanosInSecond) asInteger].
  ^ self seconds: integerSeconds nanoSeconds: nanos
  !

Item was changed:
  ----- Method: Time class>>hour:minute:second:nanoSecond: (in category 'squeak protocol') -----
+ hour: hour minute: minute second: second nanoSecond: nanoCount
+ "Answer a Time"
- hour: hour minute: minute second: second  nanoSecond: nanoCount
- "Answer a Time - only second precision for now"
 
  ^ self
+ seconds: (hour * self secondsInHour) + (minute * self secondsInMinute) + second
+ nanoSeconds: nanoCount!
- seconds: (hour * SecondsInHour) + (minute * SecondsInMinute) + second
- nanoSeconds: nanoCount
- !

Item was added:
+ ----- Method: Time class>>nanosInSecond (in category 'constants') -----
+ nanosInSecond
+ ^ 1000000000!

Item was changed:
  ----- Method: Time class>>noon (in category 'squeak protocol') -----
  noon
 
+ ^ self seconds: self secondsInDay / 2!
- ^ self seconds: (SecondsInDay / 2)
- !

Item was changed:
  ----- Method: Time class>>now (in category 'ansi protocol') -----
  now
  "Answer a Time representing the time right now - this is a 24 hour clock."
  | localUsecs localUsecsToday |
  localUsecs := self localMicrosecondClock.
+ localUsecsToday := localUsecs \\ 86400000000. "24 * 60 * 60 * 1000000"
- localUsecsToday := localUsecs \\ MicrosecondsInDay.
  ^ self
  seconds: localUsecsToday // 1000000
  nanoSeconds: localUsecsToday \\ 1000000 * 1000!

Item was added:
+ ----- Method: Time class>>secondsInDay (in category 'constants') -----
+ secondsInDay
+ ^86400!

Item was added:
+ ----- Method: Time class>>secondsInHour (in category 'constants') -----
+ secondsInHour
+ ^3600!

Item was added:
+ ----- Method: Time class>>secondsInMinute (in category 'constants') -----
+ secondsInMinute
+ ^60!

Item was added:
+ ----- Method: Time class>>squeakEpoch (in category 'constants') -----
+ squeakEpoch
+ ^ 2415386. "Julian day number of 1 Jan 1901"!

Item was changed:
  ----- Method: Time>>print24:showSeconds:showSubseconds:on: (in category 'printing') -----
  print24: hr24 showSeconds: showSeconds showSubseconds: showSubseconds on: aStream
  "Format is 'hh:mm:ss' or 'h:mm:ss am'  or, if showSeconds is false, 'hh:mm' or 'h:mm am'.
  If showSubseconds is true and our nanoSeconds are not zero, a decimal point and subseconds are added"
 
  | h m s |
  h := self hour. m := self minute. s := self second.
  hr24
  ifTrue:
  [ h < 10 ifTrue: [ aStream nextPutAll: '0' ].
  h printOn: aStream ]
  ifFalse:
  [ h > 12
  ifTrue: [h - 12 printOn: aStream]
  ifFalse:
  [h < 1
  ifTrue: [ 12 printOn: aStream ]
  ifFalse: [ h printOn: aStream ]]].
 
  aStream nextPutAll: (m < 10 ifTrue: [':0'] ifFalse: [':']).
  m printOn: aStream.
 
  showSeconds ifTrue:
  [ aStream nextPutAll: (s < 10 ifTrue: [':0'] ifFalse: [':']).
  (showSubseconds not or: [self nanoSecond = 0])
  ifTrue: [s asInteger printOn: aStream]
+ ifFalse: [s asInteger * Time nanosInSecond + self nanoSecond asInteger
+ printOn: aStream asFixedPoint: Time nanosInSecond]].
- ifFalse: [s asInteger * NanosInSecond + self nanoSecond asInteger
- printOn: aStream asFixedPoint: NanosInSecond]].
 
  hr24 ifFalse:
  [ aStream nextPutAll: (h < 12 ifTrue: [' am'] ifFalse: [' pm']) ].
  !

Item was changed:
  Object subclass: #TimeZone
  instanceVariableNames: 'offset abbreviation name'
  classVariableNames: ''
+ poolDictionaries: ''
- poolDictionaries: 'ChronologyConstants'
  category: 'Chronology-Core'!
 
  !TimeZone commentStamp: 'dtl 7/11/2009 15:03' prior: 0!
  TimeZone is a simple class to colect the information identifying a UTC time zone.
 
  offset - Duration - the time zone's offset from UTC
  abbreviation - String - the abbreviated name for the time zone.
  name - String - the name of the time zone.
 
  TimeZone class >> #timeZones returns an array of the known time zones
  TimeZone class >> #default returns the default time zone (Grenwich Mean Time)
  !

Item was changed:
  Timespan subclass: #Week
  instanceVariableNames: ''
  classVariableNames: 'StartDay'
+ poolDictionaries: ''
- poolDictionaries: 'ChronologyConstants'
  category: 'Chronology-Core'!
 
  !Week commentStamp: 'cbr 7/28/2010 18:11' prior: 0!
  I represent a week.
 
  To find out what days of the week on which Squeak is fun, select the following expression, and print it:
 
  Week dayNames!

Item was changed:
+ ----- Method: Week class>>dayNames (in category 'inquiries') -----
- ----- Method: Week class>>dayNames (in category 'squeak protocol') -----
  dayNames
 
+ ^ #(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)!
- ^ DayNames!

Item was changed:
  ----- Method: Week class>>indexOfDay: (in category 'squeak protocol') -----
  indexOfDay: aSymbol
 
+ ^ self dayNames indexOf: aSymbol!
- ^ DayNames indexOf: aSymbol!

Item was changed:
  ----- Method: Week class>>nameOfDay: (in category 'smalltalk-80') -----
  nameOfDay: anIndex
 
+ ^ self dayNames at: anIndex!
- ^ DayNames at: anIndex!

Item was changed:
  ----- Method: Week class>>startDay (in category 'squeak protocol') -----
  startDay
 
  ^ StartDay ifNil: [ StartDay
+  := self dayNames first ]
-  := DayNames first ]
  !

Item was changed:
  ----- Method: Week class>>startDay: (in category 'squeak protocol') -----
  startDay: aSymbol
 
+ (self dayNames includes: aSymbol)
- (DayNames includes: aSymbol)
  ifTrue: [ StartDay := aSymbol ]
  ifFalse: [ self error: aSymbol, ' is not a recognised day name' ]!

Item was changed:
  ----- Method: Week class>>starting:duration: (in category 'squeak protocol') -----
  starting: aDateAndTime duration: aDuration
  "Override - the duration is always one week.
  Week will start from the Week class>>startDay"
 
  | midnight delta adjusted |
  midnight := aDateAndTime asDateAndTime midnight.
+ delta := ((midnight dayOfWeek + 7 - (self dayNames indexOf: self startDay)) rem: 7) abs.
- delta := ((midnight dayOfWeek + 7 - (DayNames indexOf: self startDay)) rem: 7) abs.
  adjusted := midnight - (Duration days: delta seconds: 0).
 
  ^ super starting: adjusted duration: (Duration weeks: 1)!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Chronology-Core-dtl.59.mcz

David T. Lewis
I moved this to treated inbox. Thanks Levente for the reviews and suggestions.

Dave

On Sun, Sep 06, 2020 at 06:05:02PM +0000, [hidden email] wrote:

> A new version of Chronology-Core was added to project The Inbox:
> http://source.squeak.org/inbox/Chronology-Core-dtl.59.mcz
>
> ==================== Summary ====================
>
> Name: Chronology-Core-dtl.59
> Author: dtl
> Time: 6 September 2020, 2:05:00.620796 pm
> UUID: 99c99e87-ef4a-49ee-99eb-699c6c3dd65d
> Ancestors: Chronology-Core-ul.58
>
> Adopt simplifications from Cuis. Remove ChronologyConstants. Retain jmv author initials where possible. The shared pool is not required, it is simpler to use methods in the responsible classes.
>
> For Squeak, OneDay is now a class variable in order to continue to allow Date instances to share a Duration. Cuis creates a new Duration for each Date. Class variable Zero is similarly defined.
>
> =============== Diff against Chronology-Core-ul.58 ===============
>