diff --git a/datadog_checks_base/changelog.d/25497.fixed b/datadog_checks_base/changelog.d/25497.fixed new file mode 100644 index 0000000000000..20d377047a4b7 --- /dev/null +++ b/datadog_checks_base/changelog.d/25497.fixed @@ -0,0 +1 @@ +Fix parsing RFC3339 timestamps with fractional seconds. diff --git a/datadog_checks_base/datadog_checks/base/utils/date.py b/datadog_checks_base/datadog_checks/base/utils/date.py index 1d62f124cc0c0..106e8a03afbc5 100644 --- a/datadog_checks_base/datadog_checks/base/utils/date.py +++ b/datadog_checks_base/datadog_checks/base/utils/date.py @@ -64,7 +64,7 @@ def parse_rfc3339(s): for x in range(6): dt[x] = int(groups[x]) if groups[6] is not None: - dt[6] = int(groups[6]) + dt[6] = int(groups[6][1:7].ljust(6, '0')) tz = UTC if groups[7] is not None and groups[7] != 'Z' and groups[7] != 'z': tz_groups = _re_timezone.search(groups[7]).groups() diff --git a/datadog_checks_base/tests/base/utils/test_date.py b/datadog_checks_base/tests/base/utils/test_date.py new file mode 100644 index 0000000000000..85a9037e4a060 --- /dev/null +++ b/datadog_checks_base/tests/base/utils/test_date.py @@ -0,0 +1,33 @@ +# (C) Datadog, Inc. 2026-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +from datetime import datetime, timedelta, timezone + +import pytest + +from datadog_checks.base.utils.date import parse_rfc3339 + + +@pytest.mark.parametrize( + 'fraction, microsecond', + [ + ('', 0), + ('.0', 0), + ('.1', 100000), + ('.123', 123000), + ('.001', 1000), + ('.123456', 123456), + ('.000001', 1), + ('.123456789', 123456), + ('.999999999', 999999), + ('.000000001', 0), + (',123', 123000), + ], +) +@pytest.mark.parametrize('suffix, offset', [('Z', 0), ('+05:30', 330), ('-04:30', -270)]) +def test_parse_rfc3339_fractional_seconds(fraction: str, microsecond: int, suffix: str, offset: int): + timestamp = f'2019-02-18T16:00:06{fraction}{suffix}' + expected = datetime(2019, 2, 18, 16, 0, 6, microsecond, tzinfo=timezone(timedelta(minutes=offset))) + + assert parse_rfc3339(timestamp) == expected