Skip to content

fix(sensor): parse ISO timestamps with any fractional-second precision - #198

Open
rudycelekli wants to merge 1 commit into
uber:mainfrom
rudycelekli:fix/sensor-timestamp-fraction-digits
Open

rudycelekli wants to merge 1 commit into
uber:mainfrom
rudycelekli:fix/sensor-timestamp-fraction-digits

Conversation

@rudycelekli

@rudycelekli rudycelekli commented Oct 19, 2026 •

Copy link
Copy Markdown

What type of PR is this? (check all applicable)

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Related issue: N/A (found by reading the code; reproduced on main at 6b33dff)

What changed?
Before fromisoformat, pad/truncate the fractional-seconds group (only when it follows :SS) to 6 digits. No behavior change on 3.11+.

Why?
Sensor/adr_sensor/utils/timestamp_utils.py:31 calls datetime.fromisoformat(), which on Python 3.9/3.10 (both in the CI matrix, requires-python >=3.9) only accepts exactly 3 or 6 fractional digits. normalize_timestamp("2025-07-16T13:32:09.12345Z") or a nanosecond value ("...09.123456789Z", what Go's RFC3339Nano / protojson emit) raises ValueError("Unable to parse timestamp"). Every parser routes event times through this helper, so those events lose their timestamp (fall back to file mtime / now, invalid_timestamp diagnostics).

How did you test it?

  • Reproduction: uv run --python 3.9 python -c 'from adr_sensor.utils.timestamp_utils import normalize_timestamp as n; n("2025-07-16T13:32:09.12345Z")' -> main: ValueError; branch: 2025-07-16 13:32:09.123450+00:00. New test tests/test_utils.py::TestNormalizeTimestamp::test_iso_string_with_any_fraction_length (5 cases): py3.9 on main 5 failed; on branch 26/26 pass in test_utils.py.
  • Test suite: py3.14 613 passed; py3.9 613 passed.
  • Not tested: py3.10 full suite (same fromisoformat behavior verified directly on 3.10: rejects 1/5/9-digit fractions). On 3.11+ the new test passes on main too (it only fails on the 3.9/3.10 CI legs).

Potential risks
The change only affects the input described above; other paths go through the same code as before, and the component's existing tests pass.

On Python 3.9 and 3.10, datetime.fromisoformat() only accepts exactly 3 or
6 fractional-second digits, so normalize_timestamp() raised on RFC 3339
values such as "2025-07-16T13:32:09.12345Z" or nanosecond timestamps
(Go's RFC3339Nano). Parsers then dropped the event time and fell back to
file mtimes. Pad or truncate the fraction to microseconds before parsing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant