Repository: sharkdp/fd
File: src/filter/time.rs (Rust)

Code before:
    Before(SystemTime),
    After(SystemTime),
}

impl TimeFilter {
    fn from_str(ref_time: &SystemTime, s: &str) -> Option<SystemTime> {
        humantime::parse_duration(s)
            .map(|duration| *ref_time - duration)
            .ok()
            .or_else(|| {
                DateTime::parse_from_rfc3339(s)
                    .map(|dt| dt.into())
                    .ok()
                    .or_else(|| {
                        NaiveDate::parse_from_str(s, "%F")
                            .ok()?
                            .and_hms_opt(0, 0, 0)?
                            .and_local_timezone(Local)
                            .latest()
                    })
                    .or_else(|| {
                        NaiveDateTime::parse_from_str(s, "%F %T")
                            .ok()?
                            .and_local_timezone(Local)
                            .latest()
                    })
                    .or_else(|| {
                        let timestamp_secs = s.strip_prefix('@')?.parse().ok()?;
                        DateTime::from_timestamp(timestamp_secs, 0).map(Into::into)
                    })
                    .map(|dt| dt.into())
            })
    }

    pub fn before(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
        TimeFilter::from_str(ref_time, s).map(TimeFilter::Before)
    }

    pub fn after(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
        TimeFilter::from_str(ref_time, s).map(TimeFilter::After)
    }

    pub fn applies_to(&self, t: &SystemTime) -> bool {
        match self {
            TimeFilter::Before(limit) => t < limit,
            TimeFilter::After(limit) => t > limit,
        }
    }
}

#[cfg(test)]

Review comment (suggestion):
It's a little unfortunate that we go from a timestmp to a Zoned, and then  back to a SystemTime, which is basically the same as a timestamp. 

But I don't think converting everything else to Timestamp first would be a lot better.

Code after:
    Before(SystemTime),
    After(SystemTime),
}

impl TimeFilter {
    fn from_str(ref_time: &SystemTime, s: &str) -> Option<SystemTime> {
        s.parse::<Span>()
            .and_then(|duration| {
                Zoned::try_from(*ref_time).and_then(|zdt| zdt.checked_sub(duration))
            })
            .ok()
            .or_else(|| {
                let local_tz = TimeZone::system();
                s.parse::<Timestamp>()
                    .map(|ts| ts.to_zoned(TimeZone::UTC))
                    .ok()
                    .or_else(|| {
                        s.parse::<DateTime>()
                            .map(|dt| local_tz.to_ambiguous_zoned(dt))
                            .and_then(|zdt| zdt.later())
                            .ok()
                    })
                    .or_else(|| {
                        let timestamp_secs = s.strip_prefix('@')?.parse().ok()?;
                        Timestamp::from_second(timestamp_secs)
                            .map(|ts| ts.to_zoned(TimeZone::UTC))
                            .ok()
                    })
            })
            .map(SystemTime::from)
    }

    pub fn before(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
        TimeFilter::from_str(ref_time, s).map(TimeFilter::Before)
    }

    pub fn after(ref_time: &SystemTime, s: &str) -> Option<TimeFilter> {
        TimeFilter::from_str(ref_time, s).map(TimeFilter::After)
    }

    pub fn applies_to(&self, t: &SystemTime) -> bool {
        match self {
            TimeFilter::Before(limit) => t < limit,
            TimeFilter::After(limit) => t > limit,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;