summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThayne McCombs <astrothayne@gmail.com>2024-04-26 22:37:54 -0600
committerGitHub <noreply@github.com>2024-04-26 22:37:54 -0600
commit85cbea8dcb6ca5c4de7402373b6b83ba146ca682 (patch)
tree96d186d1910a36ed5e149609533bffd9d8bbff7d
parentbc6782624ef8d886c267c0f698e3895d9657df0e (diff)
parentffde94c10e3ba757693cc43c75becbf8127e9c80 (diff)
Merge pull request #1494 from nabellows/master
Add support for @%s time format
-rw-r--r--CHANGELOG.md1
-rw-r--r--doc/fd.112
-rw-r--r--src/filter/time.rs36
3 files changed, 44 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 08f447f..1717b85 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
## Features
- 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
diff --git a/doc/fd.1 b/doc/fd.1
index 8877317..1ac63c5 100644
--- a/doc/fd.1
+++ b/doc/fd.1
@@ -312,8 +312,9 @@ tebibytes
Filter results based on the file modification time.
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
-in time in either full RFC3339 format with time zone, or as a date or datetime in the
-local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR).
+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), or as the prefix '@'
+followed by the number of seconds since the Unix epoch (@[0-9]+).
\fB\-\-change-newer-than\fR,
.B --newer
or
@@ -324,13 +325,15 @@ Examples:
\-\-changed-within 2weeks
\-\-change-newer-than "2018-10-27 10:00:00"
\-\-newer 2018-10-27
+ \-\-changed-after @1704067200
.TP
.BI "\-\-changed-before " date|duration
Filter results based on the file modification time.
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
-in time in either full RFC3339 format with time zone, or as a date or datetime in the
-local time zone (\fIYYYY-MM-DD\fR or \fIYYYY-MM-DD HH:MM:SS\fR).
+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), or as the prefix '@'
+followed by the number of seconds since the Unix epoch (@[0-9]+).
.B --change-older-than
or
.B --older
@@ -339,6 +342,7 @@ can be used as aliases.
Examples:
\-\-changed-before "2018-10-27 10:00:00"
\-\-change-older-than 2weeks
+ \-\-older @1704067200
.TP
.BI "-o, \-\-owner " [user][:group]
Filter files by their user and/or group. Format: [(user|uid)][:(group|gid)]. Either side
diff --git a/src/filter/time.rs b/src/filter/time.rs
index 0070e5e..4777f0f 100644
--- a/src/filter/time.rs
+++ b/src/filter/time.rs
@@ -1,4 +1,4 @@
-use chrono::{DateTime, Local, NaiveDate, NaiveDateTime};
+use chrono::{DateTime, Local, NaiveDate, NaiveDateTime, Utc};
use std::time::SystemTime;
@@ -31,6 +31,13 @@ impl TimeFilter {
.and_local_timezone(Local)
.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())
})
}
@@ -135,5 +142,32 @@ mod tests {
assert!(!TimeFilter::after(&ref_time, t10s_before)
.unwrap()
.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));
}
}