diff options
author | Tim Peters <tim.peters@gmail.com> | 2002-12-22 20:58:42 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2002-12-22 20:58:42 (GMT) |
commit | d6844155725af2eb53a9bc5beb74521c4d212365 (patch) | |
tree | 36e7a57691b30b91562fd54149777938ec5a4d36 | |
parent | 83b85f1d6cce999e0d85f669df71a520632a4c87 (diff) | |
download | cpython-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.py | 6 | ||||
-rw-r--r-- | Modules/datetimemodule.c | 25 |
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. |