[squeak-dev] Time primitives

Levente Uzonyi leves at elte.hu
Wed Apr 8 08:33:45 UTC 2015


On Tue, 7 Apr 2015, David T. Lewis wrote:

> On Tue, Apr 07, 2015 at 11:42:21PM +0200, Levente Uzonyi wrote:
>> On Tue, 7 Apr 2015, David T. Lewis wrote:
>>
>>> I am away and cannot double check the code right now, but the primitives
>>> should be consistent across Cog and the interpreter VM. There had been
>>> some confusion due to the early fork between trunk and oscog, but I
>>> believe that Eliot and I got it sorted out quite a while ago.
>>
>> I can confirm this, but the primitives don't work correctly on the
>> Interpreter VM (4.10.2.2614 on linux from squeakvm.org):
>>
>> Time primUTCMicrosecondClock. "==> 2177453298247316"
>> Time primPosixMicrosecondClockWithOffset. "==> #(519745201 7200)"
>> DateAndTime now. "==> 2015-04-07T23:30:28.665+01:00"
>>
>> The same with CogVM:
>>
>> Time primUTCMicrosecondClock. "==> 3605895086935548"
>> Time primPosixMicrosecondClockWithOffset. "==> #(1428442289746346 7200)"
>> DateAndTime now. "==> 2015-04-07T23:31:32.962+01:00"
>>
>
> Why do you think this is wrong? I suspect that the one hour time zone

Let me reorder the lines to show the actual problems:


Time primUTCMicrosecondClock. "==> 2177453298247316"
Time primUTCMicrosecondClock. "==> 3605895086935548"

The value from the Interpreter VM (first line) is significantly smaller 
than the value from Cog. The former can't be right.


Time primPosixMicrosecondClockWithOffset. "==> #(519745201 7200)"
Time primPosixMicrosecondClockWithOffset. "==> #(1428442289746346 7200)"

Same here. The microseconds value from the Interpreter VM (first line) is
way smaller than what it should be.


DateAndTime now. "==> 2015-04-07T23:30:28.665+01:00"
DateAndTime now. "==> 2015-04-07T23:31:32.962+01:00"

Both values are in the CET(+1) time zone, but the actual time zone is 
CEST(+2). Both images were started in CEST.

> offset in your image is not in agreement with the three hour offset that
> your operating system is reporting. The difference in absolute microseconds
> is due to different origins in the time scale. Eliot's primitive used the
> Smalltalk epoch UTC as its origin, and mine used Posix. Neither is wrong.
>
>>>
>>> These are not necessarily set up as numbered primitives, but the
>>> implementations are there, and they can be called as named primitives in
>>> Cog/Spur and interpreter VMs.
>>>
>>> I don't know about the Pharo fork, it's quite possible that things have
>>> gotten renamed there.
>>
>> The primitives are the same, but the method names in the image are not,
>> and the latter is what matters for me. It's a pain to keep code running in
>> both branches.
>>
>>>
>>> Note, the UTC with offset primitive is important to me because of
>>> UTCDateAndTime (http://wiki.squeak.org/squeak/6197), which is designed
>>> around the notion of a single primitive answering UTC time and local
>>> offset as an atomic call to the VM.
>>
>> It seems like this primitive caches the time zone offset, which is bad
>> when there are daylight savings changes (or when the machine goes to a
>> different time zone). Here's the current value from a long running image:
>>
>> Time primPosixMicrosecondClockWithOffset. "==> #(1428442620344927 3600)"
>>
>> But the LocalePlugin's primitives seem like they know the truth:
>>
>> Locale current primTimezone. "==> 120"
>> Locale current primDST. "==> true"
>>
>
> If you are suggesting that the handling of time zones in the various images
> is less than perfect, then I will be the first to agree with you. But I don't
> think that the primitives are wrong.
>
> We have this primitive:
>
>  InterpreterPrimitives>>primitiveUtcWithOffset
> 	"Answer an array with UTC microseconds since the Posix epoch and
> 	the current seconds offset from GMT in the local time zone. An empty
> 	two element array may be supplied as a parameter.
> 	This is a named (not numbered) primitive in the null module (ie the VM)"
>
> And the unix platforms sources implement it like this (with ifdefs removed
> for clarity):
>
>  sqInt sqUnixUtcWithOffset(sqLong *microSeconds, int *offset)
>  {
>    struct timeval timeval;
>    if (gettimeofday(&timeval, NULL) == -1) return -1;
>    time_t seconds= timeval.tv_sec;
>    suseconds_t usec= timeval.tv_usec;
>    *microSeconds= seconds * 1000000 + usec;
>    *offset= localtime(&seconds)->tm_gmtoff;
>    return 0;
>  }
>
> So the operating system is telling you its best estimate of the current time
> in microseconds since the Posix epoch, as well as the local time zone offset
> in seconds at the time of the call. This is a single gettimeofday() call to
> the platform runtime library, which is about as close as we can get to a
> coherent result on general purpose unix systems.

I'm telling that the LocalePlugin can find out the correct time zone in 
case of DST changes, but it seems like gettimeofday() can't.

Levente

>
> Dave
>
>
>


More information about the Squeak-dev mailing list