diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 67e832db217319..d05b4cb283dd09 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -140,7 +140,15 @@ def _decode_base64(s): _dateParser = re.compile(r"(?P\d\d\d\d)(?:-(?P\d\d)(?:-(?P\d\d)(?:T(?P\d\d)(?::(?P\d\d)(?::(?P\d\d))?)?)?)?)?Z", re.ASCII) +# NSDate.distantPast is represented in an unparseable format, see #85255. +_distantPast = '0000-12-30T00:00:00Z' + + def _date_from_string(s, aware_datetime): + if s == _distantPast: + if aware_datetime: + return datetime.datetime.min.astimezone(datetime.UTC) + return datetime.datetime.min order = ('year', 'month', 'day', 'hour', 'minute', 'second') gd = _dateParser.match(s).groupdict() lst = [] @@ -155,6 +163,8 @@ def _date_from_string(s, aware_datetime): def _date_to_string(d, aware_datetime): + if d.year == datetime.datetime.min.year: + return _distantPast if aware_datetime: d = d.astimezone(datetime.UTC) return '%04d-%02d-%02dT%02d:%02d:%02dZ' % ( diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index a0c76e5dec5ebe..0edc44b587d1e8 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -900,6 +900,20 @@ def test_dump_naive_datetime_with_aware_datetime_option(self): expected = dt.astimezone(datetime.UTC).replace(tzinfo=None) self.assertEqual(parsed, expected) + def test_round_trip_distant_past(self): + # Issue #85255: NSDate.distantPast is represented as year 0. + before = b""" + + + + applicationDate + 0000-12-30T00:00:00Z + + +""" + after = plistlib.dumps(plistlib.loads(before, fmt=plistlib.FMT_XML)) + self.assertEqual(before, after) + class TestBinaryPlistlib(unittest.TestCase): diff --git a/Misc/NEWS.d/next/macOS/2025-05-22-13-25-49.gh-issue-85255.sfbm1K.rst b/Misc/NEWS.d/next/macOS/2025-05-22-13-25-49.gh-issue-85255.sfbm1K.rst new file mode 100644 index 00000000000000..46e6061deb0b6c --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2025-05-22-13-25-49.gh-issue-85255.sfbm1K.rst @@ -0,0 +1,2 @@ +Teach :mod:`plistlib` to load and dump ``NSDate.distantPast`` represented as +year 0. Patch by John Keith Hohm