Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.d/1442.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed ``parser.parse()`` raising ``ParserError`` for a bare 9-digit time token
(``HHMMSSmmm``), e.g. ``20010203 040506789``. Reported by @Magic-sheep (gh issue
#1442).
9 changes: 9 additions & 0 deletions src/dateutil/parser/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,15 @@ def _parse_numeric_token(self, tokens, idx, info, ymd, res, fuzzy):
res.minute = int(s[2:4])
res.second, res.microsecond = self._parsems(s[4:])

elif len_li == 9 and ymd and res.hour is None:
# HHMMSSmmm - a time with millisecond precision but no decimal
# point (e.g. the "040506789" in "20010203 040506789").
s = tokens[idx]
res.hour = int(s[:2])
res.minute = int(s[2:4])
res.second = int(s[4:6])
res.microsecond = int(s[6:9].ljust(6, "0"))

elif len_li in (8, 12, 14):
# YYYYMMDD
s = tokens[idx]
Expand Down
25 changes: 19 additions & 6 deletions tests/test_internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
code that may be difficult to reach through the standard API calls.
"""

import pytest
import sys
import warnings

from dateutil.parser._parser import _ymd
import pytest

from dateutil import tz
from dateutil.parser._parser import _ymd


@pytest.mark.smoke
Expand Down Expand Up @@ -43,8 +45,7 @@ def test_YMD_could_be_day():
###
# Test that private interfaces in _parser are deprecated properly
def test_parser_private_warns():
from dateutil.parser import _timelex, _tzparser
from dateutil.parser import _parsetz
from dateutil.parser import _parsetz, _timelex, _tzparser

with pytest.warns(DeprecationWarning):
_tzparser()
Expand All @@ -57,8 +58,7 @@ def test_parser_private_warns():


def test_parser_parser_private_not_warns():
from dateutil.parser._parser import _timelex, _tzparser
from dateutil.parser._parser import _parsetz
from dateutil.parser._parser import _parsetz, _timelex, _tzparser

with warnings.catch_warnings():
warnings.simplefilter("error")
Expand All @@ -83,3 +83,16 @@ def test_tzstr_internal_timedeltas():

assert tz1._start_delta != tz2._start_delta
assert tz1._end_delta != tz2._end_delta


@pytest.mark.smoke
def test_parser_hhmmss_milliseconds():
# A 9-digit time token is HHMMSSmmm (no decimal point), e.g. the
# "040506789" in "20010203 040506789" (gh-1442).
from datetime import datetime

from dateutil.parser import parse

expected = datetime(2001, 2, 3, 4, 5, 6, 789000)
assert parse("20010203 040506789") == expected
assert parse("20010203T040506789") == expected
Loading