Describe the bug
qdrant_client.local.datetime_utils.parse() accepts datetime strings that qdrant core rejects, so local mode silently succeeds on values that would fail server-side.
>>> from qdrant_client.local.datetime_utils import parse
>>> parse("2024-06-15 12")
datetime.datetime(2024, 6, 15, 12, 0, tzinfo=datetime.timezone.utc)
>>> parse("2024-06-15T12:30")
datetime.datetime(2024, 6, 15, 12, 30, tzinfo=datetime.timezone.utc)
Neither is an accepted format. available_formats has no %Y-%m-%d %H and no %Y-%m-%dT%H:%M, and the core list the docstring points at is RFC 3339 plus %Y-%m-%dT%H:%M:%S%.f, %Y-%m-%d %H:%M:%S%.f, %Y-%m-%d %H:%M, %Y-%m-%d.
Cause
The final fallback appends :00 to any string that failed the format list:
# Python can't parse timezones containing only hours (+HH), but it can parse timezones with hours and minutes
# So we add :00 to the assumed timezone and try parsing it again
return parse_available_formats(date_str + ":00")
It exists to complete an hour-only UTC offset (...000+01 -> ...000+01:00), but it is unguarded, so it also completes truncated datetimes:
"2024-06-15 12" + ":00" -> "2024-06-15 12:00", which matches %Y-%m-%d %H:%M
"2024-06-15T12:30" + ":00" -> "2024-06-15T12:30:00", which matches %Y-%m-%dT%H:%M:%S
Confirmed against dev (f003e6c) — neither string matches any entry in available_formats directly:
>>> from qdrant_client.local import datetime_utils as d
>>> from datetime import datetime
>>> [f for f in d.available_formats if _parses("2024-06-15 12", f)]
[]
>>> [f for f in d.available_formats if _parses("2024-06-15 12:00", f)]
['%Y-%m-%d %H:%M']
Expected behavior
The :00 retry should only apply to a string that actually ends in an hour-only offset. Anything else that fails the format list should return None, so local mode and the server agree on what is a valid datetime.
Impact
A payload or filter value with a truncated datetime is accepted by QdrantLocal and rejected by a real Qdrant instance, and "2024-06-15 12" is read as 12:00:00 rather than surfacing as invalid input. It is the local/server congruence property this client tests for elsewhere.
Environment
- qdrant-client @
dev (f003e6c)
- Python 3.14
Describe the bug
qdrant_client.local.datetime_utils.parse()accepts datetime strings that qdrant core rejects, so local mode silently succeeds on values that would fail server-side.Neither is an accepted format.
available_formatshas no%Y-%m-%d %Hand no%Y-%m-%dT%H:%M, and the core list the docstring points at is RFC 3339 plus%Y-%m-%dT%H:%M:%S%.f,%Y-%m-%d %H:%M:%S%.f,%Y-%m-%d %H:%M,%Y-%m-%d.Cause
The final fallback appends
:00to any string that failed the format list:It exists to complete an hour-only UTC offset (
...000+01->...000+01:00), but it is unguarded, so it also completes truncated datetimes:"2024-06-15 12"+":00"->"2024-06-15 12:00", which matches%Y-%m-%d %H:%M"2024-06-15T12:30"+":00"->"2024-06-15T12:30:00", which matches%Y-%m-%dT%H:%M:%SConfirmed against
dev(f003e6c) — neither string matches any entry inavailable_formatsdirectly:Expected behavior
The
:00retry should only apply to a string that actually ends in an hour-only offset. Anything else that fails the format list should returnNone, so local mode and the server agree on what is a valid datetime.Impact
A payload or filter value with a truncated datetime is accepted by
QdrantLocaland rejected by a real Qdrant instance, and"2024-06-15 12"is read as12:00:00rather than surfacing as invalid input. It is the local/server congruence property this client tests for elsewhere.Environment
dev(f003e6c)