Tcl Source Code

View Ticket
Login
Ticket UUID: 16e4fc30961de5dc969639eaef7354022b683102
Title: year int overflow - clock format of very large date / JD is wrong - if switches into negative value (+24 hours difference).
Type: Bug Version: 8.5 (check trunc)
Submitter: sebres Created on: 2014-06-26 21:52:24
Subsystem: 06. Time Measurement Assigned To: sebres
Priority: 1 Zero Severity: Minor
Status: Pending Last Modified: 2022-08-02 11:35:33
Resolution: Fixed Closed By: nobody
    Closed on:
Description:
year int overflow while format of very large date:

% clock format 0xfffffffffffffff
Sun Feb 05 14:56:15 CET 1269743
% clock format 0xffffffffffffff
Thu Apr 28 13:52:15 CET 2127340
% clock format 0xfffffffffffff
Sun Apr 12 04:48:15 CET 1604708

todo: check trunc + other branch 
todo: check overflow in tcl::clock::__intern_functions__ or ::tcl::clock::format only, possible leap year calculation.
User Comments: sebres added on 2022-08-02 11:35:33:

Basically all current tcl-versions overflow after year 5874790:

  % clock format [set i 185628797193599] -gmt 1
  Mon Dec 31 23:59:59 GMT 5874790
  % clock format [incr i] -gmt 1
  Tue Jan 01 00:00:00 GMT 5874789
The fix in tclclockmod or speedup branches is minimalist, since without large effort it was possible only up to y2e9 (so I set an internal range TCL_MIN_SECONDS to TCL_MAX_SECONDS as ±0x00F0000000000000L), because by some larger values the internal calculation may also overflow (somewhere by the julianday which is signed 32-int now)...
  % package require tclclockmod
  % clock format [set i 0x00F0000000000000] -gmt 1
  Mon Dec 19 09:04:00 GMT 2140702833
  % clock format [incr i] -gmt 1
  integer value too large to represent
Anyway it is more than 360 times larger than by tcl now (and most important it would not overflow silently anymore).


sebres added on 2019-01-25 20:57:50:

Fix is pushed for below-mentioned JD-bug (as announced, using variant 1), see [1a47e63d8d], thus ticket could be closed, if branch gets merged.


sebres added on 2019-01-23 17:11:24:

I found still another similar issue (because minor, won't open new ticket):

  % clock format [expr {-210866803200 - 0}] -format {%J -- %Y-%m-%d %T} -gmt true
  0000000 -- 4713-01-01 00:00:00
  % clock format [expr {-210866803200 - 1}] -format {%J -- %Y-%m-%d %T} -gmt true
- 0000000 -- 4713-01-01 23:59:59
+ -000001 -- 4714-12-31 23:59:59
  % clock format [expr {-210866803200 - 86400}] -format {%J -- %Y-%m-%d %T} -gmt true
- -000001 -- 4714-12-31 00:00:00
+ -000002 -- 4714-12-31 00:00:00

Julian day, if traverses over 0 into negative (from year 4713 B.C.E to 4714 B.C.E), becomes negative value first if it is switched a complete day back (24 hours are invalid).
Because julian day used also in the internal calculations, as one can see in the second call (red-marked result), the formated date is therefore totally wrong. Expected value is green-marked.

There are 2 variants to fix this:
1. JD to -1, and seconds of day to 86399 (simplest case to implement or to fix it)
2. JD to 0, and seconds of day to -1 (more complex case, because at the moment value of day-seconds is rather positive everywhere in internal calculations, thus then many adjustments are necessary in this case).

I've fixed it (variant 1) in my internal branches (and tclclockmod), will port it later in sebres-8-6-clock-speedup branch.

BTW, I don't understand also, why it has padding 7 at all (and for which reasons it may be necessary).


sebres added on 2017-08-08 15:22:46:

Fixed in branch sebres-8-6-clock-speedup-cr1 (commit [3efed18ef8]).

Can be closed if branch get merged.