diff --git a/app/api/inspections.py b/app/api/inspections.py index fc7146b..2998190 100644 --- a/app/api/inspections.py +++ b/app/api/inspections.py @@ -62,24 +62,33 @@ _UUID_RE = re.compile( def _parse_datetime(value): - """Parse an ISO 8601 datetime string; return None on failure. + """Parse an ISO 8601 datetime string; return a naive Eastern datetime. Handles the formats produced by both the web forms and iOS - ISO8601DateFormatter(), which appends a 'Z' UTC suffix: - 2026-05-28T09:41:00 (web form) + ISO8601DateFormatter(): + 2026-05-28T09:41:00 (web form, already Eastern-naive) 2026-05-28T09:41:00.000 (web form with ms) - 2026-05-28T09:41:00Z (iOS ISO8601DateFormatter) - 2026-05-28T09:41:00.000000Z (iOS with fractional seconds) + 2026-05-28T09:41:00Z (iOS ISO8601DateFormatter, UTC) + 2026-05-28T09:41:00.000000Z (iOS with fractional seconds, UTC) + + Values ending with 'Z' are treated as UTC and converted to Eastern. + Values without a timezone suffix are assumed to already be Eastern-local. """ if not value: return None - from datetime import datetime - # Strip trailing 'Z' (UTC marker) so strptime can parse it as naive datetime. - # The system treats all datetimes as Eastern-local; UTC offset is ignored. + from datetime import datetime, timezone as _tz + from app.utils.time_utils import EASTERN + + is_utc = isinstance(value, str) and value.endswith('Z') normalised = value.rstrip('Z') if isinstance(value, str) else value for fmt in ('%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M:%S.%f', '%Y-%m-%d'): try: - return datetime.strptime(normalised, fmt) + dt = datetime.strptime(normalised, fmt) + if is_utc: + dt = (dt.replace(tzinfo=_tz.utc) + .astimezone(EASTERN) + .replace(tzinfo=None)) + return dt except (ValueError, TypeError): pass return None