diff --git a/src/pendulum/parsing/__init__.py b/src/pendulum/parsing/__init__.py index d88c089a..c4e1bd69 100644 --- a/src/pendulum/parsing/__init__.py +++ b/src/pendulum/parsing/__init__.py @@ -49,7 +49,7 @@ # Subsecond part (optional) " (?P" " (?:[.|,])" # Subsecond separator (optional) - r" (?P\d{1,9})" # Subsecond + r" (?P\d+)" # Subsecond (truncated to microseconds later) " )?" ")?" "$", diff --git a/src/pendulum/parsing/iso8601.py b/src/pendulum/parsing/iso8601.py index c65d249e..c7df029c 100644 --- a/src/pendulum/parsing/iso8601.py +++ b/src/pendulum/parsing/iso8601.py @@ -49,7 +49,7 @@ # Subsecond part (optional) " (?P" " (?:[.,])" # Subsecond separator (optional) - r" (?P\d{1,9})" # Subsecond + r" (?P\d+)" # Subsecond (truncated to microseconds later) " )?" # Timezone offset " (?P" diff --git a/tests/parsing/test_parse_iso8601.py b/tests/parsing/test_parse_iso8601.py index ed2d3988..f9b3a3e1 100644 --- a/tests/parsing/test_parse_iso8601.py +++ b/tests/parsing/test_parse_iso8601.py @@ -82,6 +82,10 @@ "2016-10-06T12:34:56.123456789+05:30", datetime(2016, 10, 6, 12, 34, 56, 123456, FixedTimezone(+19800)), ), + # More fractional digits than microsecond precision (truncated) + ("2016-10-06T12:34:56.123456789012", datetime(2016, 10, 6, 12, 34, 56, 123456)), + ("12:34:56.123456789012", time(12, 34, 56, 123456)), + ("20161006T123456,123456789012", datetime(2016, 10, 6, 12, 34, 56, 123456)), # Week date with time ("2008-W39-6T09", datetime(2008, 9, 27, 9, 0, 0, 0)), ], diff --git a/tests/parsing/test_parsing.py b/tests/parsing/test_parsing.py index 8151ce12..d1be87a1 100644 --- a/tests/parsing/test_parsing.py +++ b/tests/parsing/test_parsing.py @@ -700,3 +700,19 @@ def test_exif_edge_case(): assert parsed.hour == 15 assert parsed.minute == 45 assert parsed.second == 28 + + +def test_subsecond_more_than_nine_digits(): + # Fractional seconds beyond microsecond precision are truncated (issue #935) + text = "2016-10-06T12:34:56.123456789012" + + parsed = parse(text) + + assert parsed.microsecond == 123456 + + # The common parser handles the same input + text = "2016/10/06 12:34:56.123456789012" + + parsed = parse(text) + + assert parsed.microsecond == 123456