Add support for @%s time format

This commit is contained in:
Nathan Bellows 2024-02-12 02:05:41 -08:00
parent 969316cc0e
commit b0a8848f68
3 changed files with 38 additions and 5 deletions

View File

@ -3,6 +3,7 @@
## Features ## Features
- Add `dir` as an alias to `directory` when using `-t` \ `--type`, see #1460 and #1464 (@Ato2207). - Add `dir` as an alias to `directory` when using `-t` \ `--type`, see #1460 and #1464 (@Ato2207).
- Add support for @%s date format in time filters similar to GNU date (seconds since Unix epoch for --older/--newer), see #1493 (@nabellows)
## Bugfixes ## Bugfixes

12
doc/fd.1 vendored
View File

@ -312,8 +312,9 @@ tebibytes
Filter results based on the file modification time. Filter results based on the file modification time.
Files with modification times greater than the argument will be returned. Files with modification times greater than the argument will be returned.
The argument can be provided as a duration (\fI10h, 1d, 35min\fR) or as a specific point The argument can be provided as a duration (\fI10h, 1d, 35min\fR) or as a specific point
in time in either full RFC3339 format with time zone, or as a date or datetime in the in time as full RFC3339 format with time zone, as a date or datetime in the
local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR). local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR), or as the prefix '@'
followed by the number of seconds since the Unix epoch (@[0-9]+).
\fB\-\-change-newer-than\fR, \fB\-\-change-newer-than\fR,
.B --newer .B --newer
or or
@ -324,13 +325,15 @@ Examples:
\-\-changed-within 2weeks \-\-changed-within 2weeks
\-\-change-newer-than "2018-10-27 10:00:00" \-\-change-newer-than "2018-10-27 10:00:00"
\-\-newer 2018-10-27 \-\-newer 2018-10-27
\-\-changed-after @1704067200
.TP .TP
.BI "\-\-changed-before " date|duration .BI "\-\-changed-before " date|duration
Filter results based on the file modification time. Filter results based on the file modification time.
Files with modification times less than the argument will be returned. Files with modification times less than the argument will be returned.
The argument can be provided as a duration (\fI10h, 1d, 35min\fR) or as a specific point The argument can be provided as a duration (\fI10h, 1d, 35min\fR) or as a specific point
in time in either full RFC3339 format with time zone, or as a date or datetime in the in time as full RFC3339 format with time zone, as a date or datetime in the
local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR). local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR), or as the prefix '@'
followed by the number of seconds since the Unix epoch (@[0-9]+).
.B --change-older-than .B --change-older-than
or or
.B --older .B --older
@ -339,6 +342,7 @@ can be used as aliases.
Examples: Examples:
\-\-changed-before "2018-10-27 10:00:00" \-\-changed-before "2018-10-27 10:00:00"
\-\-change-older-than 2weeks \-\-change-older-than 2weeks
\-\-older @1704067200
.TP .TP
.BI "-o, \-\-owner " [user][:group] .BI "-o, \-\-owner " [user][:group]
Filter files by their user and/or group. Format: [(user|uid)][:(group|gid)]. Either side Filter files by their user and/or group. Format: [(user|uid)][:(group|gid)]. Either side

View File

@ -1,4 +1,4 @@
use chrono::{DateTime, Local, NaiveDate, NaiveDateTime}; use chrono::{DateTime, Local, NaiveDate, NaiveDateTime, Utc};
use std::time::SystemTime; use std::time::SystemTime;
@ -31,6 +31,13 @@ impl TimeFilter {
.and_local_timezone(Local) .and_local_timezone(Local)
.latest() .latest()
}) })
.or_else(|| {
let timestamp_secs = s.strip_prefix('@')?.parse().ok()?;
NaiveDateTime::from_timestamp_opt(timestamp_secs, 0)?
.and_local_timezone(Utc)
.latest()
.map(Into::into)
})
.map(|dt| dt.into()) .map(|dt| dt.into())
}) })
} }
@ -135,5 +142,26 @@ mod tests {
assert!(!TimeFilter::after(&ref_time, t10s_before) assert!(!TimeFilter::after(&ref_time, t10s_before)
.unwrap() .unwrap()
.applies_to(&t1m_ago)); .applies_to(&t1m_ago));
let ref_timestamp = 1707723412u64; // Mon Feb 12 07:36:52 UTC 2024
let ref_time = DateTime::parse_from_rfc3339("2024-02-12T07:36:52+00:00")
.unwrap()
.into();
let t1m_ago = ref_time - Duration::from_secs(60);
let t1s_later = ref_time + Duration::from_secs(1);
// Timestamp only supported via '@' prefix
assert!(TimeFilter::before(&ref_time, &ref_timestamp.to_string()).is_none());
assert!(TimeFilter::before(&ref_time, &format!("@{}", ref_timestamp))
.unwrap()
.applies_to(&t1m_ago));
assert!(!TimeFilter::before(&ref_time, &format!("@{}", ref_timestamp))
.unwrap()
.applies_to(&t1s_later));
assert!(!TimeFilter::after(&ref_time, &format!("@{}", ref_timestamp))
.unwrap()
.applies_to(&t1m_ago));
assert!(TimeFilter::after(&ref_time, &format!("@{}", ref_timestamp))
.unwrap()
.applies_to(&t1s_later));
} }
} }