summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorAlexander Belopolsky <alexander.belopolsky@gmail.com>2011-01-07 19:59:19 (GMT)
committerAlexander Belopolsky <alexander.belopolsky@gmail.com>2011-01-07 19:59:19 (GMT)
commitc64708ae48d07ac906ae29e7ac19a6173a9926df (patch)
tree0fe64e3d7b06b9e889131d6224f791590aa83907 /Modules
parent696efdd03f40d5a135961af54946b56028b323bd (diff)
downloadcpython-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.c47
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] */