[squeak-dev] A UTC based implementation of DateAndTime

David T. Lewis lewis at mail.msen.com
Sun May 25 17:48:44 UTC 2014

I have been working on a variation of class DateAndTime that replaces its
instance variables (seconds offset jdn nanos) with two instance variables,
utcMicroseconds to represent microseconds elapsed since the Posix epoch, and
localOffsetSeconds to represent the local time zone offset. When instantiating
the time now, A single call primitiveUtcWithOffset is used to obtain these
two values atomically as reported by the underlying platform.

There are several advantages to this representation of DateAndTime, the most
important of which is that its magnitude is unambiguous regardless of daylight
savings transitions in local time zones.

This is my attempt to address some historical baggage in Squeak. The VM
reports time related to the local time zone, and the image attempts to
convert to UTC (sometimes incorrectly). A UTC based representation makes the
implementation of time zone tables more straightforward (see for example
the Olson time zone tables in TimeZoneDatabase on SqueakMap).

I am attaching the source code as a SAR file that can be loaded into a fully
updated Squeak trunk image. The conversion process is slow, so be patient
if you load it.

This can be run on either an intepreter VM or Cog, but if you use Cog, please
use a version dated June 2013 or later (the VM in the Squeak 4.5 all-in-one
is fine).

I am also attaching a copy of LXTestDateAndTimePerformance, which can be
used to compare the performance of some basic DateAndTime functions.

Performance of the UTC based DateAndTime is generally favorable compared to
the original. Here is what I see on my system (smaller numbers are better).

LXTestDateAndTimePerformance test results using the original Squeak DateAndTime
on an interpreter VM:
	#testNow->10143 .
	#testEquals->30986 .
	#testGreaterThan->80199 .
	#testLessThan->75912 .
	#testPrintString->10429 .

LXTestDateAndTimePerformance test results using the new UTC based DateAndTime
on an interpreter VM:
	#testNow->6423 .
	#testEquals->31625 .
	#testGreaterThan->22999 .
	#testLessThan->18514 .
	#testPrintString->12502 .

(CC to Brent Pinkney, author of the excellent Squeak Chronology package)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: UtcDateAndTime-dtl.sar
Type: application/octet-stream
Size: 30521 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20140525/44ec36bb/UtcDateAndTime-dtl.obj
-------------- next part --------------
'From Squeak4.5 of 25 May 2014 [latest update: #13773] on 25 May 2014 at 10:02:29 am'!
Object subclass: #LXTestDateAndTimePerformance
	instanceVariableNames: 'delta dt times'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'DTL'!
!LXTestDateAndTimePerformance commentStamp: 'dtl 5/25/2014 09:36' prior: 0!
LXTestDateAndTimePerformance new test.!
]style[(28 10)c000000126,!

!LXTestDateAndTimePerformance methodsFor: 'initialize-release' stamp: 'dtl 5/25/2014 09:32'!
	super initialize.
	delta := (30 * 24 * 3600 + 127) seconds.
	dt := '1500-11-25T14:51:03.506615-21:23:31' asDateAndTime.
	times := (1 to: 10000) collect: [:e | dt := dt + delta].
! !

!LXTestDateAndTimePerformance methodsFor: 'testing' stamp: 'dtl 5/25/2014 09:57'!
	^ {
		#testNow -> self testNow .
		#testEquals -> self testEquals .
		#testGreaterThan -> self testGreaterThan .
		#testLessThan -> self testLessThan .
		#testPrintString -> self testPrintString .
		#testStringAsDateAndTime -> self testStringAsDateAndTime
	}! !

!LXTestDateAndTimePerformance methodsFor: 'testing' stamp: 'dtl 5/25/2014 09:39'!
	^ Time millisecondsToRun: [
		times do: [:time |
			times do: [:e | e = time ]]]! !

!LXTestDateAndTimePerformance methodsFor: 'testing' stamp: 'dtl 5/25/2014 09:39'!
	^ Time millisecondsToRun: [
		times do: [:time |
			times do: [:e | e > time ]]]! !

!LXTestDateAndTimePerformance methodsFor: 'testing' stamp: 'dtl 5/25/2014 09:38'!
	^ Time millisecondsToRun: [
		times do: [:time |
			times do: [:e | e < time ]]]! !

!LXTestDateAndTimePerformance methodsFor: 'testing' stamp: 'dtl 5/25/2014 09:42'!
	^ Time millisecondsToRun: [5000000 timesRepeat: [DateAndTime now]]! !

!LXTestDateAndTimePerformance methodsFor: 'testing' stamp: 'dtl 5/25/2014 09:50'!
	^ Time millisecondsToRun: [50 timesRepeat: [times do: [:time | time asString]]]! !

!LXTestDateAndTimePerformance methodsFor: 'testing' stamp: 'dtl 5/25/2014 09:55'!
	| strings |
	strings := times collect: [:e | e printString].
	^ Time millisecondsToRun: [50 timesRepeat: [strings do: [:string | string asDateAndTime]]]! !

More information about the Squeak-dev mailing list