diff options
author | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2011-01-07 19:59:19 (GMT) |
---|---|---|
committer | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2011-01-07 19:59:19 (GMT) |
commit | c64708ae48d07ac906ae29e7ac19a6173a9926df (patch) | |
tree | 0fe64e3d7b06b9e889131d6224f791590aa83907 /Modules | |
parent | 696efdd03f40d5a135961af54946b56028b323bd (diff) | |
download | cpython-c64708ae48d07ac906ae29e7ac19a6173a9926df.zip cpython-c64708ae48d07ac906ae29e7ac19a6173a9926df.tar.gz cpython-c64708ae48d07ac906ae29e7ac19a6173a9926df.tar.bz2 |
Issue #10827: Changed the rules for 2-digit years. The time.asctime
function will now format any year when time.accept2dyear is false and
will accept years >= 1000 otherwise. The year range accepted by
time.mktime and time.strftime is still system dependent, but
time.mktime will now accept full range supported by the OS. Conversion
of 2-digit years to 4-digit is deprecated.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/timemodule.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 4b45f6e..94265c6 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -312,34 +312,42 @@ gettmarg(PyObject *args, struct tm *p) &p->tm_wday, &p->tm_yday, &p->tm_isdst)) return 0; - /* XXX: Why 1900? If the goal is to interpret 2-digit years as those in - * 20th / 21st century according to the POSIX standard, we can just treat - * 0 <= y < 100 as special. Year 100 is probably too ambiguous and should - * be rejected, but years 101 through 1899 can be passed through. + /* If year is specified with less than 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. */ - if (y < 1900) { + if (y < 1000) { PyObject *accept = PyDict_GetItemString(moddict, "accept2dyear"); int acceptval = accept != NULL && PyObject_IsTrue(accept); if (acceptval == -1) return 0; if (acceptval) { - if (69 <= y && y <= 99) - y += 1900; - else if (0 <= y && y <= 68) + if (0 <= y && y < 69) y += 2000; + else if (69 <= y && y < 100) + y += 1900; else { PyErr_SetString(PyExc_ValueError, "year out of range"); return 0; } - } - /* XXX: When accept2dyear is false, we don't have to reject y < 1900. - * Consider removing the following else-clause. */ - else { - PyErr_SetString(PyExc_ValueError, - "year out of range"); - return 0; + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Century info guessed for a 2-digit year.", 1) != 0) + return 0; } } p->tm_year = y - 1900; @@ -462,6 +470,15 @@ time_strftime(PyObject *self, PyObject *args) else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; + /* XXX: Reportedly, some systems have issues formating dates prior to year + * 1900. These systems should be identified and this check should be + * moved to appropriate system specific section below. */ + if (buf.tm_year < 0) { + PyErr_Format(PyExc_ValueError, "year=%d is before 1900; " + "the strftime() method requires year >= 1900", + buf.tm_year + 1900); + } + /* Normalize tm_isdst just in case someone foolishly implements %Z based on the assumption that tm_isdst falls within the range of [-1, 1] */ |