]> granicus.if.org Git - python/commitdiff
Issue #11930: Remove year >= 1000 limitation from datetime.strftime.
authorAlexander Belopolsky <alexander.belopolsky@gmail.com>
Mon, 2 May 2011 17:14:24 +0000 (13:14 -0400)
committerAlexander Belopolsky <alexander.belopolsky@gmail.com>
Mon, 2 May 2011 17:14:24 +0000 (13:14 -0400)
Patch by Victor Stinner.

Doc/library/datetime.rst
Lib/datetime.py
Lib/test/datetimetester.py
Modules/_datetimemodule.c

index c637f6a44d07e3e46e11167e61e6472599e1cca3..2eb5ea0f1ff87323823831658b83eeedb8b9dfcb 100644 (file)
@@ -1750,8 +1750,7 @@ format codes.
 |           | decimal number [00,99].        |       |
 +-----------+--------------------------------+-------+
 | ``%Y``    | Year with century as a decimal | \(5)  |
-|           | number [0001,9999] (strptime), |       |
-|           | [1000,9999] (strftime).        |       |
+|           | number [0001,9999].            |       |
 +-----------+--------------------------------+-------+
 | ``%z``    | UTC offset in the form +HHMM   | \(6)  |
 |           | or -HHMM (empty string if the  |       |
@@ -1785,10 +1784,7 @@ Notes:
    calculations when the day of the week and the year are specified.
 
 (5)
-   For technical reasons, :meth:`strftime` method does not support
-   dates before year 1000: ``t.strftime(format)`` will raise a
-   :exc:`ValueError` when ``t.year < 1000`` even if ``format`` does
-   not contain ``%Y`` directive.  The :meth:`strptime` method can
+   The :meth:`strptime` method can
    parse years in the full [1, 9999] range, but years < 1000 must be
    zero-filled to 4-digit width.
 
index 1ae7cb5305a02d252f7c840782dce664b3e4f66d..1f8c8f79bdc6ec8067c970b771a73d076b5695ee 100644 (file)
@@ -172,10 +172,6 @@ def _format_time(hh, mm, ss, us):
 
 # Correctly substitute for %z and %Z escapes in strftime formats.
 def _wrap_strftime(object, format, timetuple):
-    year = timetuple[0]
-    if year < 1000:
-        raise ValueError("year=%d is before 1000; the datetime strftime() "
-                         "methods require year >= 1000" % year)
     # Don't call utcoffset() or tzname() unless actually needed.
     freplace = None # the string to use for %f
     zreplace = None # the string to use for %z
index 38f3b8f19bd95a9c8527d692ff82f810cfc90100..4a62bd4a9efa2d4b3d03d64b9d7272a60d82a885 100644 (file)
@@ -1289,12 +1289,10 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase):
         self.assertTrue(self.theclass.min)
         self.assertTrue(self.theclass.max)
 
-    def test_strftime_out_of_range(self):
-        # For nasty technical reasons, we can't handle years before 1000.
-        cls = self.theclass
-        self.assertEqual(cls(1000, 1, 1).strftime("%Y"), "1000")
-        for y in 1, 49, 51, 99, 100, 999:
-            self.assertRaises(ValueError, cls(y, 1, 1).strftime, "%Y")
+    def test_strftime_y2k(self):
+        for y in (1, 49, 70, 99, 100, 999, 1000, 1970):
+            self.assertEqual(self.theclass(y, 1, 1).strftime("%Y"),
+                             '%04d' % y)
 
     def test_replace(self):
         cls = self.theclass
index a19c0c355be3f2e033a184777ec41c0948f681aa..747be45246c9152f4c126bcc0390afba8fa7b733 100644 (file)
@@ -1166,31 +1166,6 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
     if (!pin)
         return NULL;
 
-    /* Give up if the year is before 1000.
-     * Python strftime() plays games with the year, and different
-     * games depending on whether envar PYTHON2K is set.  This makes
-     * years before 1000 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(PyLong_Check(pyyear));
-        year = PyLong_AsLong(pyyear);
-        Py_DECREF(pyyear);
-        if (year < 1000) {
-            PyErr_Format(PyExc_ValueError, "year=%ld is before "
-                         "1000; the datetime strftime() "
-                         "methods require year >= 1000",
-                         year);
-            return NULL;
-        }
-    }
-
     /* Scan the input format, looking for %z/%Z/%f escapes, building
      * a new format.  Since computing the replacements for those codes
      * is expensive, don't unless they're actually used.