msg125339 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
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) *  |
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) *  |
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) *  |
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) *  |
Date: 2011-01-04 18:49 |
But if it fails, why not just let it fail? |
|
|
msg125356 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
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) *  |
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) *  |
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) *  |
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) *  |
Date: 2011-01-07 20:41 |
Commit link: r87829 |
|
|
msg125714 - (view) |
Author: STINNER Victor (vstinner) *  |
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) *  |
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]. |
|
|