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