DateAndTime class>>#fromSeconds: and #fromMilliseconds: have problems

48 views
Skip to first unread message

Richard Sargent

unread,
Apr 29, 2020, 1:27:32 PM4/29/20
to VA Smalltalk
This test was run in a 32-bit 9.2 image, but I suspect the defect is ancient.

 DateAndTime fromSeconds:  0              1901-01-01T00:00:00-08:00
 DateAndTime fromSeconds: -1              1900-12-31T23:59:59-08:00
 DateAndTime fromSeconds: -12             1900-12-31T23:59:48-08:00
 DateAndTime fromSeconds: -123            1900-12-31T23:57:57-08:00
 DateAndTime fromSeconds: -1234           1900-12-31T23:39:26-08:00
 DateAndTime fromSeconds: -12345          1900-12-31T20:34:15-08:00
 DateAndTime fromSeconds: -123456         1900-12-30T13:42:24-08:00
 DateAndTime fromSeconds: -1234567        1900-12-17T17:03:53-08:00
 DateAndTime fromSeconds: -12345678       1900-08-11T02:38:42-08:00
 DateAndTime fromSeconds: -123456789      1897-02-01T02:26:51-08:00
 DateAndTime fromSeconds: -1234567890     1861-11-17T00:28:30-07:52:58
 DateAndTime fromSeconds: -12345678901    1509-10-13T04:44:59-07:52:58

 DateAndTime fromMilliseconds:  0              1901-01-01T00:00:00-08:00
 DateAndTime fromMilliseconds: -1              1900-12-31T23:59:59.999-08:00
 DateAndTime fromMilliseconds: -12             1900-12-31T23:59:59.988-08:00
 DateAndTime fromMilliseconds: -123            1900-12-31T23:59:59.877-08:00
 DateAndTime fromMilliseconds: -1234           1900-12-31T23:59:58.766-08:00
 DateAndTime fromMilliseconds: -12345          1900-12-31T23:59:47.655-08:00
 DateAndTime fromMilliseconds: -123456         1900-12-31T23:57:56.544-08:00
 DateAndTime fromMilliseconds: -1234567        1900-12-31T23:39:25.433-08:00
 DateAndTime fromMilliseconds: -12345678       1900-12-31T20:34:14.322-08:00
 DateAndTime fromMilliseconds: -123456789      1900-12-30T13:42:23.-7-8-9-08:00
 DateAndTime fromMilliseconds: -1234567890     1900-12-17T17:03:52.-8-9-08:00
 DateAndTime fromMilliseconds: -12345678901    1900-08-11T02:38:41.-90-1-08:00
 DateAndTime fromMilliseconds: -123456789012   1897-02-01T02:26:50.0-1-2-08:00
 DateAndTime fromMilliseconds: -1234567890123  1861-11-17T00:28:29.-1-2-3-07:52:58
 DateAndTime fromMilliseconds: -12345678901234 1509-10-13T04:44:58.-2-3-4-07:52:58



Richard Sargent

unread,
Apr 29, 2020, 1:39:39 PM4/29/20
to VA Smalltalk
DateAndTime class>>#fromSeconds:offsetSeconds: does appear to work correctly based on all the numbers I tried below.

Richard Sargent

unread,
Apr 29, 2020, 2:27:44 PM4/29/20
to VA Smalltalk
Spoke too soon!
DateAndTime fromSeconds: -2545887519165/1000 offsetSeconds: -25200 yields 1820-04-28T10:01:20.-1-6-5-07:00

Richard Sargent

unread,
Apr 29, 2020, 3:45:43 PM4/29/20
to VA Smalltalk
Aha! It looks like DateAndTime>>#printMilliseconds:on: fails to recognize "negative time" from negative milliseconds when printing the millisecond portion of the time.

Changing DateAndTime>>#printOn: to add %_ to the time format correctly prints 1820-04-28T10:01:20.835.
Doing so also makes the subsequent (and defective) statement self printMilliseconds: self asMilliseconds on: aStream. unnecessary.


It turns out that once upon a time, we didn't have standard time. We used local mean time (LMT). If you use a date far enough in the past, you get LMT time zone entries with a time zone offset that is directly related to the named place's longitude. In the case of Los Angeles, this is -07:52:58. Weird, but what can you do?

John O'Keefe

unread,
May 18, 2020, 1:51:18 PM5/18/20
to VA Smalltalk
It would be nice if just adding '%_' to the time format would work, but unfortunately it isn't quite that simple:
 - %_ doesn't supply a leading period (.), so you instead need to add '.%_' to get the proper separator
 - %_ doesn't work correctly (in this context) for a time with zero milliseconds - it will print a single 0 in this case

So I think something like this will work better:

| tfmt |
tfmt := (self asMilliseconds rem: 1000) ~= 0
ifTrue: [ tfmt := 'T%H:%M:%S.%_' ]     "$NON-NLS$"
ifFalse: [ tfmt := 'T%H:%M:%S' ].     "$NON-NLS$"
Locale current lcTime copy
dFmt: '%Y-%m-%d'; "$NON-NLS$"
tFmt: tfmt;
printDate: self date on: aStream;
printTime: self time on: aStream.
" self printMilliseconds: self asMilliseconds on: aStream."

DateAndTime fromMilliseconds: -123456789               1900-12-30T13:42:23.211-05:00
DateAndTime year:2020 day: 101 hour: 11 minute: 34 second:17               2020-04-10T11:34:17-04:00

John

Richard Sargent

unread,
May 18, 2020, 1:59:01 PM5/18/20
to VA Smalltalk
On Mon, May 18, 2020 at 10:51 AM John O'Keefe <john.o...@gmail.com> wrote:
It would be nice if just adding '%_' to the time format would work, but unfortunately it isn't quite that simple:
 - %_ doesn't supply a leading period (.), so you instead need to add '.%_' to get the proper separator
 - %_ doesn't work correctly (in this context) for a time with zero milliseconds - it will print a single 0 in this case

Good point, John. I agree with your proposal. The results look good, like what one would expect.

--
You received this message because you are subscribed to a topic in the Google Groups "VA Smalltalk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/va-smalltalk/Sbm8zmD-3GA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to va-smalltalk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/va-smalltalk/41574481-961a-45bd-bb12-439f47ef73e6%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages