summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-12-22 20:58:42 (GMT)
committerTim Peters <tim.peters@gmail.com>2002-12-22 20:58:42 (GMT)
commitd6844155725af2eb53a9bc5beb74521c4d212365 (patch)
tree36e7a57691b30b91562fd54149777938ec5a4d36
parent83b85f1d6cce999e0d85f669df71a520632a4c87 (diff)
downloadcpython-d6844155725af2eb53a9bc5beb74521c4d212365.zip
cpython-d6844155725af2eb53a9bc5beb74521c4d212365.tar.gz
cpython-d6844155725af2eb53a9bc5beb74521c4d212365.tar.bz2
I give up: unless I write my own strftime by hand, datetime just can't
be trusted with years before 1900, so now we raise ValueError if a date or datetime or datetimetz .strftime() method is called with a year before 1900.
-rw-r--r--Lib/test/test_datetime.py6
-rw-r--r--Modules/datetimemodule.c25
2 files changed, 31 insertions, 0 deletions
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py
index ca26872..6838e47 100644
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -868,6 +868,12 @@ class TestDate(unittest.TestCase):
self.failUnless(self.theclass.min)
self.failUnless(self.theclass.max)
+ def test_srftime_out_of_range(self):
+ # For nasty technical reasons, we can't handle years before 1900.
+ cls = self.theclass
+ self.assertEqual(cls(1900, 1, 1).strftime("%Y"), "1900")
+ for y in 1, 49, 51, 99, 100, 1000, 1899:
+ self.assertRaises(ValueError, cls(y, 1, 1).strftime, "%Y")
#############################################################################
# datetime tests
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index 28f61bd..a9675d6 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -940,6 +940,31 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple)
assert(object && format && timetuple);
assert(PyString_Check(format));
+ /* Give up if the year is before 1900.
+ * Python strftime() plays games with the year, and different
+ * games depending on whether envar PYTHON2K is set. This makes
+ * years before 1900 a nightmare, even if the platform strftime
+ * supports them (and not all do).
+ * We could get a lot farther here by avoiding Python's strftime
+ * wrapper and calling the C strftime() directly, but that isn't
+ * an option in the Python implementation of this module.
+ */
+ {
+ long year;
+ PyObject *pyyear = PySequence_GetItem(timetuple, 0);
+ if (pyyear == NULL) return NULL;
+ assert(PyInt_Check(pyyear));
+ year = PyInt_AsLong(pyyear);
+ Py_DECREF(pyyear);
+ if (year < 1900) {
+ PyErr_Format(PyExc_ValueError, "year=%ld is before "
+ "1900; the datetime strftime() "
+ "methods require year >= 1900",
+ year);
+ return NULL;
+ }
+ }
+
/* Scan the input format, looking for %z and %Z escapes, building
* a new format. Since computing the replacements for those codes
* is expensive, don't unless they're actually used.