> The leap year handling in the Convert() routine in generic/tclDate.c is
> incorrect. Leap years are divisible by 4, unless it's divisible by 100,
> in which case it's a leap year only if it's divisible by 400. Hence
> 2000 is a leap year, but 2100 is not.
cripes... i thought i had sent them a fix for that a year ago :)
+ scriptic...@auto.genned.post wrote:
+
+ > The leap year handling in the Convert() routine in generic/tclDate.c
+ > is incorrect. <snip accurate statement>
+ cripes... i thought i had sent them a fix for that a year ago :)
Well, it's clearly wrong, but can anyone tell me where it would matter?
I ran a few cases with clock format adding chunks of time to <now> to
step over the 2000 leap year, and got correct output. In what contexts
would this Convert() routine be called from standard TCL commands?
(if it is merely there for C programs to call, they can use a correct
algorithm instead...)
--
Michael L. Siemon We must know the truth, and we must
m...@panix.com love the truth we know, and we must
act according to the measure of our love.
-- Thomas Merton
Submitted by: Isaac Hollander
OperatingSystem: Sun Solaris
Synopsis: incorrect leap year handling in generic/tclDate.c
ReproducibleScript:
This is already reported as bugID 1985, but I can't figure out how to
update an existing bug. Please close out bugID 1985 and use this bug
report.
The leap year handling in the Convert() routine in generic/tclDate.c is
incorrect. Leap years are divisible by 4, unless it's divisible by 100,
in which case it's a leap year only if it's divisible by 400. Hence
2000 is a leap year, but 2100 is not.
The code is incorrect in all versions of tcl I've looked at from 8.0p2
through the latest code in CVS.
Patch:
$ diff -c tclDate.c tclDate.c.orig
*** tclDate.c Thu May 6 17:32:51 1999
--- tclDate.c.orig Mon Feb 10 13:03:15 1997
***************
*** 430,439 ****
Julian += DaysInMonth[i];
if (Year >= EPOCH) {
for (i = EPOCH; i < Year; i++)
! Julian += 365 + ( (i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0
)) );
} else {
for (i = Year; i < EPOCH; i++)
! Julian -= 365 + ( (i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0
)) );
}
Julian *= SECSPERDAY;
Julian += TclDateTimezone * 60L;
--- 430,439 ----
Julian += DaysInMonth[i];
if (Year >= EPOCH) {
for (i = EPOCH; i < Year; i++)
! Julian += 365 + (i % 4 == 0);
} else {
for (i = Year; i < EPOCH; i++)
! Julian -= 365 + (i % 4 == 0);
}
Julian *= SECSPERDAY;
Julian += TclDateTimezone * 60L;
$
PatchFiles:
generic/tclDate.c
Comments:
This is a crucial Y2K issue. Scriptics's Y2K statement discusses the 2
digit year issue in great details, but does not address proper leap year
handling.
I seem to remember you did - check www.deja.com to see. I would hazard
a guess that between the move between 3 or 4 sites it either got lost or
a bug that was fixed got 'unfixed' somewhere along the line...
--
<URL: mailto:lvi...@cas.org> Quote: Saving the world before bedtime.
<*> O- <URL: http://www.purl.org/NET/lvirden/>
Unless explicitly stated to the contrary, nothing in this posting
should be construed as representing my employer's opinions.
The main place is that Scriptics has assured its paying customers about
it's 'y2k' compliance and most customers consider correct leap year handling
to be a part of the responsibility of a vendor.
+ According to Michael L. Siemon <m...@panix.com>:
+ :Well, it's clearly wrong, but can anyone tell me where it would matter?
+
+ The main place is that Scriptics has assured its paying customers about
+ it's 'y2k' compliance and most customers consider correct leap year handling
+ to be a part of the responsibility of a vendor.
Ummm, I understand that (I have had to assure my management that TCL
was Y2K compliant.) I agree that the function must be fixed or removed.
What I don't understand (and am asking) is _where is it in fact used_ in
core functionality? as I cannot in easy cases generate a 2000-leapyear
error with the commands I would expect to show up the problem.
-- Scott Redman
We'll reapply the patch, although I don't think it will actually affect
anything. The epoch doesn't extend past 2038, so you can't actually process
dates that are within the problem range. This will basically be dead code
until the 2038 issue is resolved.
___________________________________________________________
Scott Stanton 650-210-0105 tel
Sr. Software Engineer 650-210-0101 fax
Scriptics Corporation scott....@scriptics.com
The Tcl Platform Company http://www.scriptics.com
tcl>clock scan "Feb 28 2000"
925516800
tcl>clock scan "Feb 29 2000"
Error: unable to convert date-time string "Feb 29 2000"
This is un-good.
-- cary
Maybe I'm screwed up about this, and I forget the rule anyway, but I
thought that 2000 would not be a leap year, so this would be right.
-- Scott
-- Scott
Gawain Lavers wrote:
>
> Cary O'Brien wrote:
> >
> > Yikes.
> >
> > tcl>clock scan "Feb 28 2000"
> > 925516800
> > tcl>clock scan "Feb 29 2000"
> > Error: unable to convert date-time string "Feb 29 2000"
> >
> > This is un-good.
> >
> > -- cary
>
Cool, I'll try to remember it now. I was afraid that it was going to be
another case of me being right and the rest of the world being wrong.
clock scan "Feb 29 00:00:00 2000"
If you don't put the time-of-day, it uses the date for the
time-of-day instead, and assumes the current year for the year.
Probably needs better documentation?
-- Scott
Scott Redman wrote:
>
> It's busted even for "Feb 29 1996". I'm looking into it...
>
> -- Scott
>
I see the bug report is only for 8.1. 8.0.4, and 8.0.2 are the same.
Or has someone already mentioned that.
Gordon
To answer my own question: The bug report is spurious -- there is NO ERROR
in the
algorithm of Convert. As I saw when I looked up the source at work. In fact, the
routine explicitly errors out before START_OF_TIME and after END_OF_TIME, and
in that range (on all platforms) the leap year algorithm is strictly Julian. The
routine does not even NEED the (correct, Gregorian) initialization of the number
of days in February -- but that is a trivial nicety. By using a pure
Julian algorithm
in the loop on years, two expression evaluations per pass are saved, with
no loss
of correctness.
(Note: try "clock scan 3/1/2100" and you will see what I mean -- the
failure case
that the bug report is trying to "fix" is not a possible case.)
Now, when the Y2L38 Bug is addressed, this code will _have_ to be revisited! :-)
+ Yikes.
+
+ tcl>clock scan "Feb 28 2000"
+ 925516800
+ tcl>clock scan "Feb 29 2000"
+ Error: unable to convert date-time string "Feb 29 2000"
+
+ This is un-good.
It is indeed -- what are you executing? no TCL I have tried
does this.
-- Scott
"Michael L. Siemon" wrote:
>
> In article <mls-140599...@mls.dialup.access.net>, m...@panix.com
> (Michael L. Siemon) wrote:
>
> To answer my own question: The bug report is spurious -- there is NO ERROR
> in the
> algorithm of Convert. As I saw when I looked up the source at work. In fact, the
> routine explicitly errors out before START_OF_TIME and after END_OF_TIME, and
> in that range (on all platforms) the leap year algorithm is strictly Julian. The
> routine does not even NEED the (correct, Gregorian) initialization of the number
> of days in February -- but that is a trivial nicety. By using a pure
> Julian algorithm
> in the loop on years, two expression evaluations per pass are saved, with
> no loss
> of correctness.
>
> (Note: try "clock scan 3/1/2100" and you will see what I mean -- the
> failure case
> that the bug report is trying to "fix" is not a possible case.)
>
> Now, when the Y2L38 Bug is addressed, this code will _have_ to be revisited! :-)
At least on Solaris 2.7, the 2038 deadline is solved by time_t being longer
than a long...
> Yikes.
>
> tcl>clock scan "Feb 28 2000"
> 925516800
> tcl>clock scan "Feb 29 2000"
> Error: unable to convert date-time string "Feb 29 2000"
>
> This is un-good.
>
> -- cary
The correct syntax seems to be:
clock scan "Feb 29, 2000"
Note the coma after the day. If you just say "Feb 29 2000", well TCL
silently ignores the year and try
to convert using the current year. Take a look in the sources at
generic/tclGetDate.y around line
230.
Hope that helps Francois
I e-mailed Scriptics to say that their web site y2k page should be
updated to reflect this and Brent Welch mailed back with :-
<extract>
The problem is the lack of a comma between "Feb 29" and "2000".
Try this, which works:
clock scan "Feb 29, 2000"
<extract>
But this is still odd behaviour as other dates don't require this comma.
Gordon
Which is a time *this* year. Guess what; it is doing something other
than what you think it is doing! Try:
puts [clock format [clock scan "Feb 28 2000"] -gmt 1]
to get something in a canonical *human-readable* form.
Donal.
--
Donal K. Fellows http://www.cs.man.ac.uk/~fellowsd/ fell...@cs.man.ac.uk
-- The small advantage of not having California being part of my country would
be overweighed by having California as a heavily-armed rabid weasel on our
borders. -- David Parsons <o r c @ p e l l . p o r t l a n d . o r . u s>
clock format [clock scan "feb 29 ,2000"]
The comma in the docu is meant seriosly. Perhaps it should be stated
in the doc that it is no spelling mistake:
The acceptable formats are mm/dd?/yy?,
monthname dd ?, yy?, dd monthname ?yy? and day, dd monthname yy.
^!!!!!!
Greetings!
Volker
I wonder if it would be worthwhile to come up with patches for more
date formats?