Repository: qdrant/qdrant
File: lib/segment/src/types.rs (Rust)

Code before:
impl DateTimeWrapper {
    /// Qdrant's representation of datetime as timestamp is an i64 of microseconds
    pub fn timestamp(&self) -> i64 {
        self.0.timestamp_micros()
    }

    pub fn from_timestamp(ts: i64) -> Option<Self> {
        Some(Self(chrono::DateTime::from_timestamp_micros(ts)?))
    }
}

impl<'de> Deserialize<'de> for DateTimePayloadType {
    /// Parses RFC3339 datetime strings used in REST/JSON `datetime_range` filters.
    /// Returns a clear user-facing error when the format is invalid.
    /// Example accepted value: `2014-01-01T00:00:00Z`.
    ///
    /// For binary formats (CBOR/MessagePack/WAL), delegates to chrono's deserializer
    /// which handles timestamps and other non-string representations.
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        if !deserializer.is_human_readable() {
            return chrono::DateTime::<chrono::Utc>::deserialize(deserializer)
                .map(DateTimePayloadType::from);
        }

        let str_datetime: Cow<'de, str> = Cow::deserialize(deserializer)?;

        match DateTimePayloadType::from_str(str_datetime.as_ref()) {
            Ok(datetime) => Ok(datetime),
            Err(_) => Err(serde::de::Error::custom(format!(
                "'{str_datetime}' does not match accepted datetime format (RFC3339). Example: 2014-01-01T00:00:00Z"
            ))),
        }
    }
}

impl FromStr for DateTimePayloadType {
    type Err = chrono::ParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        // Attempt to parse the input string in RFC 3339 format
        if let Ok(datetime) = chrono::DateTime::parse_from_rfc3339(s)
            // Attempt to parse default to-string format
            .or_else(|_| chrono::DateTime::from_str(s))
            // Attempt to parse the input string in the specified formats:
            // - YYYY-MM-DD'T'HH:MM:SS-HHMM (timezone without colon)
            // - YYYY-MM-DD HH:MM:SS-HHMM (timezone without colon)
            .or_else(|_| chrono::DateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.f%#z"))
            .or_else(|_| chrono::DateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f%#z"))

Review comment (suggestion):
`chrono::DateTime::deserialize` always deserializes through string:
https://github.com/chronotope/chrono/blob/v0.4.43/src/datetime/serde.rs#L93-L100
So `is_human_readable` check is not required.

Code after:
impl DateTimeWrapper {
    /// Qdrant's representation of datetime as timestamp is an i64 of microseconds
    pub fn timestamp(&self) -> i64 {
        self.0.timestamp_micros()
    }

    pub fn from_timestamp(ts: i64) -> Option<Self> {
        Some(Self(chrono::DateTime::from_timestamp_micros(ts)?))
    }
}

impl<'de> Deserialize<'de> for DateTimePayloadType {
    /// Parses RFC3339 datetime strings used in REST/JSON `datetime_range` filters.
    /// Returns a clear user-facing error when the format is invalid.
    /// Example accepted value: `2014-01-01T00:00:00Z`.
    ///
    /// Binary formats (CBOR/MessagePack/WAL) also serialize as RFC3339 strings, so we reuse
    /// the same parsing path everywhere.
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let str_datetime: Cow<'de, str> = Cow::deserialize(deserializer)?;

        match DateTimePayloadType::from_str(str_datetime.as_ref()) {
            Ok(datetime) => Ok(datetime),
            Err(_) => Err(serde::de::Error::custom(format!(
                "'{str_datetime}' does not match accepted datetime format (RFC3339). Example: 2014-01-01T00:00:00Z"
            ))),
        }
    }
}

impl FromStr for DateTimePayloadType {
    type Err = chrono::ParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        // Attempt to parse the input string in RFC 3339 format
        if let Ok(datetime) = chrono::DateTime::parse_from_rfc3339(s)
            // Attempt to parse default to-string format
            .or_else(|_| chrono::DateTime::from_str(s))
            // Attempt to parse the input string in the specified formats:
            // - YYYY-MM-DD'T'HH:MM:SS-HHMM (timezone without colon)
            // - YYYY-MM-DD HH:MM:SS-HHMM (timezone without colon)
            .or_else(|_| chrono::DateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.f%#z"))
            .or_else(|_| chrono::DateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S%.f%#z"))
            .map(|dt| chrono::DateTime::<chrono::Utc>::from(dt).into())
        {
            return Ok(datetime);
        }