Issue 10827: Functions in time module should support year < 1900 when accept2dyear = 0 (original) (raw)

Issue10827

Created on 2011-01-04 16:48 by belopolsky, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue10827.diff belopolsky,2011-01-04 18:30
issue10827a.diff belopolsky,2011-01-04 19:02
issue10827b.diff belopolsky,2011-01-05 16:50
issue10827c.diff belopolsky,2011-01-07 01:04
Messages (12)
msg125339 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-04 16:48
""" > http://docs.python.org/library/time.html#time-y2kissues > "Values 100–1899 are always illegal." Why are these values illegal? The GNU libc accepts year in [1900-2^31; 2^31-1] (tm_year in [-2147483648; 2147481747]). If time.accept2dyear=False, we should at least accept years in [1; 9999]. The system libc would raise an error (return NULL) if it doesn't know how to format years older than 1900. """ -- Victor Stinner at
msg125343 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-04 17:30
> The system libc would raise an error (return NULL) if it doesn't know > how to format years older than 1900. As experience with asctime has shown, system libc can do whatever it pleases with out of range values including overrunning a fixed size buffer, returning non-sensical values etc. However, now that we have control over asctime implemetation (see issue 8013), I don't see any problem in supporting at least year > 999 in time.asctime and time.ctime. (Supporting full [1900-maxint, maxint] range would involve a decision on whether to fill < 4-digit values.) Some extra care would be required for time.strftime() because some systems may not support year < 1900 as well as others. It looks like POSIX does not make any strong mandates: "tm_year is a signed value; therefore, years before 1900 may be represented." http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html and regardless of what POSIX or C standards have to say, this is the area where systems a known to have spotty compliance records.
msg125345 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-04 18:30
I am attaching a patch. While working on the patch, I noticed that although time.accept2dyear is documented as boolean, the current code expects int and treats any non-int including True as 0: >>> time.accept2dyear = True; time.asctime((99,) + (0,)*8) Traceback (most recent call last): File "", line 1, in ValueError: year >= 1900 required >>> time.accept2dyear = 1; time.asctime((99,) + (0,)*8) 'Mon Jan 1 00:00:00 1999' This is clearly a bug. (Although Y2K note contradicts time.accept2dyear documentation.) Supporting year < 1900 would be a feature in my view, but I agree with SilentGhost that once we extended support to 5+ digit years, it is odd to keep year >= 1900 restriction.
msg125349 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-04 18:38
On Tue, Jan 4, 2011 at 1:30 PM, Alexander Belopolsky <report@bugs.python.org> wrote: .. > This is clearly a bug.  (Although Y2K note contradicts time.accept2dyear documentation.) > PyObject_IsTrue() may fail - this is probably the reason for the current odd logic. My patch should be fixed top respect that, but I still maintain that time.accept2dyear = True should work as expected. (Would also make True the default rather 1.)
msg125353 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2011-01-04 18:49
But if it fails, why not just let it fail?
msg125356 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-04 19:02
On Tue, Jan 4, 2011 at 1:49 PM, Georg Brandl <report@bugs.python.org> wrote: .. > But if it fails, why not just let it fail? > Sure. That's what I meant by fixing the patch. See new patch attached.
msg125432 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-05 16:50
Attached patch, issue10827b.diff, fixes the accept2dyear = True issue and removes unnecessary struct_time to tuple conversion, but otherwise does not change the Y2K behavior. The code handling accept2dyear is refactored so that it is now easy to accept y < 1900 in accept2dyear = False mode. The patch also includes unit tests.
msg125609 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-07 00:57
Attached patch, issue10827c.diff, implements the following logic in gettmarg: /* If year is specified with less that 4 digits, its interpretation * depends on the accept2dyear value. * * If accept2dyear is true (default), a backward compatibility behavior is * invoked as follows: * * - for 2-digit year, century is guessed according to POSIX rules for * %y strptime format: 21st century for y < 69, 20th century * otherwise. A deprecation warning is issued when century * information is guessed in this way. * * - for 3-digit or negative year, a ValueError exception is raised. * * If accept2dyear is false (set by the program or as a result of a * non-empty value assigned to PYTHONY2K environment variable) all year * values are interpreted as given. */ It is easy to restore year >= 1900 limit for strftime, but I would rather add tests that time.strftime either produces correct values or raises ValueError and see if buildbots discover any platform bugs.
msg125707 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-07 20:39
Committed in 87829. I added a year >= 1900 check in time.strftime for now because removing or relaxing this limit should be done in coordination with similar datetime module issue. See #1777412. See also python-dev discussion starting at http://mail.python.org/pipermail/python-dev/2011-January/107186.html
msg125708 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2011-01-07 20:41
Commit link: r87829
msg125714 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-01-07 21:41
I tried time.asctime() on Windows 32 bits (compiled with Visual Studio) with accept2dyear=False: it accepts years in [-2^31; 2^31-1], cool.
msg125791 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011-01-08 16:38
time.asctime(), time.ctime() and time.strftime() are no more not limited for the year field if accept2dyear=0. Except with Visual Studio or on Solaris: the year is limited to the range [1; 9999].
History
Date User Action Args
2022-04-11 14:57:10 admin set github: 55036
2011-01-08 16:38:02 vstinner set nosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhostmessages: +
2011-01-07 22:59:33 belopolsky link issue1777412 dependencies
2011-01-07 21:41:52 vstinner set nosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhostmessages: +
2011-01-07 20:41:52 belopolsky set status: open -> closednosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhostmessages: +
2011-01-07 20:39:46 belopolsky set versions: + Python 3.2nosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhostmessages: + resolution: fixedsuperseder: datetime.strftime dislikes years before 1900stage: commit review -> resolved
2011-01-07 01:04:57 belopolsky set files: + issue10827c.diffnosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhost
2011-01-07 00:57:15 belopolsky set nosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhostmessages: +
2011-01-05 16:50:42 belopolsky set files: + issue10827b.diffmessages: + nosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhoststage: commit review
2011-01-04 19:02:30 belopolsky set files: + issue10827a.diffmessages: + nosy:georg.brandl, belopolsky, vstinner, Trundle, SilentGhost
2011-01-04 18:49:51 georg.brandl set nosy: + georg.brandlmessages: +
2011-01-04 18:38:55 belopolsky set nosy:belopolsky, vstinner, Trundle, SilentGhostmessages: +
2011-01-04 18:30:45 belopolsky set files: + issue10827.diffmessages: + keywords: + patchnosy:belopolsky, vstinner, Trundle, SilentGhost
2011-01-04 17:32:00 Trundle set nosy: + Trundle
2011-01-04 17:30:03 belopolsky set nosy:belopolsky, vstinner, SilentGhostmessages: +
2011-01-04 16:48:19 belopolsky create