Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 1 addition & 106 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pkg-fmt = "zip"

[dependencies]
argmax = "0.4.0"
chrono = "0.4.45"
jiff = "0.2"
clap = { version = "4.6", features = ["env"] }
faccess = "0.2.4"
nix = { version = "0.31", features = ["fs", "user"] }
Expand Down
3 changes: 1 addition & 2 deletions src/find/matchers/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ mod tests {
fn test_group_matcher() {
use crate::find::matchers::{group::GroupMatcher, tests::get_dir_entry_for, Matcher};
use crate::find::tests::FakeDependencies;
use chrono::Local;
use nix::unistd::{Gid, Group};
use std::fs::File;
use std::os::unix::fs::MetadataExt;
Expand All @@ -122,7 +121,7 @@ mod tests {
);

// Testing a non-existent group name
let time_string = Local::now().format("%Y%m%d%H%M%S").to_string();
let time_string = jiff::Zoned::now().strftime("%Y%m%d%H%M%S").to_string();
let matcher = GroupMatcher::from_group_name(time_string.as_str());
assert!(
matcher.is_none(),
Expand Down
24 changes: 12 additions & 12 deletions src/find/matchers/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use chrono::DateTime;
use std::{
fs::File,
io::{stderr, Write},
Expand Down Expand Up @@ -157,11 +155,12 @@ impl Ls {
let group =
uucore::entries::gid2grp(metadata.gid()).unwrap_or_else(|_| metadata.gid().to_string());
let size = metadata.size();
let last_modified = {
let system_time = metadata.modified().unwrap();
let now_utc: DateTime<chrono::Utc> = system_time.into();
now_utc.format("%b %e %H:%M")
};
let last_modified = metadata
.modified()
.ok()
.and_then(|t| jiff::Timestamp::try_from(t).ok())
.map(|ts| ts.strftime("%b %e %H:%M").to_string())
.unwrap_or_default();
let path = file_info.path().to_string_lossy();

match writeln!(
Expand Down Expand Up @@ -230,11 +229,12 @@ impl Ls {
let hard_links = 0;
let user = 0;
let group = 0;
let last_modified = {
let system_time = metadata.modified().unwrap();
let now_utc: DateTime<chrono::Utc> = system_time.into();
now_utc.format("%b %e %H:%M")
};
let last_modified = metadata
.modified()
.ok()
.and_then(|t| jiff::Timestamp::try_from(t).ok())
.map(|ts| ts.strftime("%b %e %H:%M").to_string())
.unwrap_or_default();
let path = file_info.path().to_string_lossy();

match writeln!(
Expand Down
48 changes: 28 additions & 20 deletions src/find/matchers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ use self::time::{
use self::type_matcher::{TypeMatcher, XtypeMatcher};
use self::user::{NoUserMatcher, UserMatcher};
use ::regex::Regex;
use chrono::{DateTime, Datelike, NaiveDate, NaiveDateTime, Utc};
use fs::FileSystemMatcher;
use ls::Ls;
use std::{
Expand Down Expand Up @@ -372,35 +371,42 @@ fn convert_arg_to_comparable_value_and_suffix(
/// When (time) is not provided, it will be automatically filled in as 00:00:00
/// such as: "jan 01, 2025" = "jan 01, 2025 00:00:00" -> 1735689600000
fn parse_date_str_to_timestamps(date_str: &str) -> Option<i64> {
if let Ok(datetime) = NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S") {
return Some(datetime.and_utc().timestamp_millis());
let to_utc_millis = |dt: jiff::civil::DateTime| {
Some(
jiff::tz::TimeZone::UTC
.to_timestamp(dt)
.ok()?
.as_millisecond(),
)
};
if let Ok(datetime) = jiff::civil::DateTime::strptime("%Y-%m-%d %H:%M:%S", date_str) {
return to_utc_millis(datetime);
}
if let Ok(date) = NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
return Some(date.and_hms_opt(0, 0, 0)?.and_utc().timestamp_millis());
if let Ok(date) = jiff::civil::Date::strptime("%Y-%m-%d", date_str) {
return to_utc_millis(date.to_datetime(jiff::civil::Time::midnight()));
}

let regex_pattern =
r"^(?P<month_day>\w{3} \d{2})?(?:, (?P<year>\d{4}))?(?: (?P<time>\d{2}:\d{2}:\d{2}))?$";
let re = Regex::new(regex_pattern);

if let Some(captures) = re.ok()?.captures(date_str) {
let now = Utc::now();
let month_day = captures
.get(1)
.map_or(format!("{} {}", now.format("%b"), now.format("%d")), |m| {
m.as_str().to_string()
});
let now = jiff::Timestamp::now().to_zoned(jiff::tz::TimeZone::UTC);
let month_day = captures.get(1).map_or(
format!("{} {}", now.strftime("%b"), now.strftime("%d")),
|m| m.as_str().to_string(),
);
// If no year input.
let year = match captures.get(2) {
Some(m) => m.as_str().parse().ok()?,
None => now.year(),
None => i32::from(now.year()),
};
// If the user does not enter a specific time, it will be filled with 0
let time_str = captures.get(3).map_or("00:00:00", |m| m.as_str());
let date_time_str = format!("{month_day}, {year} {time_str}");
let datetime = NaiveDateTime::parse_from_str(&date_time_str, "%b %d, %Y %H:%M:%S").ok()?;
let utc_datetime = DateTime::<Utc>::from_naive_utc_and_offset(datetime, Utc);
Some(utc_datetime.timestamp_millis())
let datetime =
jiff::civil::DateTime::strptime("%b %d, %Y %H:%M:%S", &date_time_str).ok()?;
to_utc_millis(datetime)
} else {
None
}
Expand Down Expand Up @@ -1821,12 +1827,14 @@ mod tests {

// pass if return current time.
let none_date_timestamps = parse_date_str_to_timestamps("");
let now_but_zero_hour_min_sec = Utc::now()
.date_naive()
.and_hms_opt(0, 0, 0)
let midnight = jiff::Timestamp::now()
.to_zoned(jiff::tz::TimeZone::UTC)
.date()
.to_datetime(jiff::civil::Time::midnight());
let now_but_zero_hour_min_sec = jiff::tz::TimeZone::UTC
.to_timestamp(midnight)
.unwrap()
.and_utc()
.timestamp_millis();
.as_millisecond();
assert_eq!(none_date_timestamps, Some(now_but_zero_hour_min_sec));

// A year of non-ASCII decimal digits must be rejected, not panic.
Expand Down
Loading
Loading