From cd5290edf0f3d65162890b79255dfc47d5293e14 Mon Sep 17 00:00:00 2001 From: Yuri Zmytrakov Date: Mon, 1 Sep 2025 15:17:18 +0200 Subject: [PATCH] fix: Ensure Normalize func preserves milliseconds precision Normalize function for datetime strings did not preserve milliseconds, causing the `/search` endpoint return incorrect results. This change ensures that milliseconds are retained when normalized. --- .../core/stac_fastapi/core/datetime_utils.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/stac_fastapi/core/stac_fastapi/core/datetime_utils.py b/stac_fastapi/core/stac_fastapi/core/datetime_utils.py index 87911ac5..d33c3027 100644 --- a/stac_fastapi/core/stac_fastapi/core/datetime_utils.py +++ b/stac_fastapi/core/stac_fastapi/core/datetime_utils.py @@ -17,22 +17,32 @@ def format_datetime_range(date_str: str) -> str: """ def normalize(dt): + """Normalize datetime string and preserve millisecond precision.""" dt = dt.strip() if not dt or dt == "..": return ".." dt_obj = rfc3339_str_to_datetime(dt) dt_utc = dt_obj.astimezone(timezone.utc) - return dt_utc.strftime("%Y-%m-%dT%H:%M:%SZ") + + if dt_obj.microsecond > 0: + return dt_utc.isoformat(timespec="milliseconds").replace("+00:00", "Z") + else: + return dt_utc.strftime("%Y-%m-%dT%H:%M:%SZ") if not isinstance(date_str, str): return "../.." + + if "/" in date_str and ".." in date_str: + return date_str + if "/" not in date_str: - return f"{normalize(date_str)}/{normalize(date_str)}" + return normalize(date_str) + try: start, end = date_str.split("/", 1) + return f"{normalize(start)}/{normalize(end)}" except Exception: return "../.." - return f"{normalize(start)}/{normalize(end)}" # Borrowed from pystac - https://github.com/stac-utils/pystac/blob/f5e4cf4a29b62e9ef675d4a4dac7977b09f53c8f/pystac/utils.py#L370-L394