# HG changeset patch
# User Brock Mendel <jbrockmendel@gmail.com>
# Date 1524281129 25200
#      Fri Apr 20 20:25:29 2018 -0700
# Node ID 171626906013db217843f0b8004d8ca878edc176
# Parent  5e875cf83befdeedf8885323b4c05aab54aba21c
Fix for B.Y.d format corner case #687

Add changelog file

diff --git a/changelog.d/687.bugfix.rst b/changelog.d/687.bugfix.rst
new file mode 100644
--- /dev/null
+++ b/changelog.d/687.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed incorrect parsing of certain dates earlier than 100 AD when repesented in the form "%B.%Y.%d", e.g. "December.0031.30". (gh issue #687, pr #700)
diff --git a/dateutil/parser/_parser.py b/dateutil/parser/_parser.py
--- a/dateutil/parser/_parser.py
+++ b/dateutil/parser/_parser.py
@@ -458,10 +458,38 @@
                 raise ValueError('Year is already set')
             self.ystridx = len(self) - 1
 
+    def _resolve_from_stridxs(self):
+        """
+        Try to resolve the identities of year/month/day elements using
+        ystridx, mstridx, and dstridx, if enough of these are specified.
+        """
+        strids = {'y': self.ystridx, 'm': self.mstridx, 'd': self.dstridx}
+        strids = {key: strids[key] for key in strids if strids[key] is not None}
+
+        if len(self) == 3 and len(strids) == 2:
+            # we can back out the remaining stridx value
+            missing = [x for x in range(3) if x not in strids.values()]
+            key = [x for x in ['y', 'm', 'd'] if x not in strids]
+            assert len(missing) == len(key) == 1
+            key = key[0]
+            val = missing[0]
+            strids[key] = val
+
+        assert len(self) == len(strids)  # otherwise this should not be called
+        out = {'y': None, 'm': None, 'd': None}
+        out.update({key: self[strids[key]] for key in strids})
+        return (out['y'], out['m'], out['d'])
+
     def resolve_ymd(self, yearfirst, dayfirst):
         len_ymd = len(self)
         year, month, day = (None, None, None)
 
+        strids = {'y': self.ystridx, 'm': self.mstridx, 'd': self.dstridx}
+        strids = {key: strids[key] for key in strids if strids[key] is not None}
+        if (len(self) == len(strids) > 0 or
+                (len(self) == 3 and len(strids) == 2)):
+            return self._resolve_from_stridxs()
+
         mstridx = self.mstridx
 
         if len_ymd > 3:
@@ -470,13 +498,17 @@
             # One member, or two members with a month string
             if mstridx is not None:
                 month = self[mstridx]
-                del self[mstridx]
+                # since mstridx is 0 or 1, self[mstridx-1] always
+                # looks up the other element
+                other = self[mstridx - 1]
+            else:
+                other = self[0]
 
             if len_ymd > 1 or mstridx is None:
-                if self[0] > 31:
-                    year = self[0]
+                if other > 31:
+                    year = other
                 else:
-                    day = self[0]
+                    day = other
 
         elif len_ymd == 2:
             # Two members with numbers
diff --git a/dateutil/test/test_parser.py b/dateutil/test/test_parser.py
--- a/dateutil/test/test_parser.py
+++ b/dateutil/test/test_parser.py
@@ -1106,3 +1106,9 @@
     # constructed with an invalid value
     with pytest.raises(ValueError):
         parse(value)
+
+
+def test_BYd_corner_case():
+    # GH#687
+    res = parse('December.0031.30')
+    assert res == datetime(31, 12, 30)