diff --git a/Cargo.lock b/Cargo.lock index c38215bff..4fc465b71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -537,7 +537,6 @@ name = "coreutils" version = "0.5.0" dependencies = [ "bincode", - "chrono", "clap", "clap_complete", "clap_mangen", @@ -4011,7 +4010,6 @@ dependencies = [ name = "uu_touch" version = "0.5.0" dependencies = [ - "chrono", "clap", "filetime", "fluent", @@ -4122,9 +4120,9 @@ dependencies = [ name = "uu_uptime" version = "0.5.0" dependencies = [ - "chrono", "clap", "fluent", + "jiff", "thiserror 2.0.17", "utmp-classic", "uucore", @@ -4204,7 +4202,6 @@ dependencies = [ "blake2b_simd", "blake3", "bstr", - "chrono", "clap", "codspeed-divan-compat", "crc-fast", diff --git a/Cargo.toml b/Cargo.toml index 1f94036e5..c4109656b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -311,11 +311,6 @@ binary-heap-plus = "0.5.0" bstr = "1.9.1" bytecount = "0.6.8" byteorder = "1.5.0" -chrono = { version = "0.4.41", default-features = false, features = [ - "std", - "alloc", - "clock", -] } clap = { version = "4.5", features = ["wrap_help", "cargo", "color"] } clap_complete = "4.4" clap_mangen = "0.2" @@ -341,11 +336,7 @@ icu_locale = "2.0.0" icu_provider = "2.0.0" indicatif = "0.18.0" itertools = "0.14.0" -jiff = { version = "0.2.10", default-features = false, features = [ - "std", - "alloc", - "tz-system", -] } +jiff = "0.2.18" libc = "0.2.172" linux-raw-sys = "0.12" lscolors = { version = "0.21.0", default-features = false, features = [ @@ -541,7 +532,6 @@ yes = { optional = true, version = "0.5.0", package = "uu_yes", path = "src/uu/y #pin_cc = { version="1.0.61, < 1.0.62", package="cc" } ## cc v1.0.62 has compiler errors for MinRustV v1.32.0, requires 1.34 (for `std::str::split_ascii_whitespace()`) [dev-dependencies] -chrono.workspace = true ctor.workspace = true filetime.workspace = true glob.workspace = true diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index b891522cc..c8c369138 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -53,7 +53,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -64,7 +64,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -504,7 +504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -824,9 +824,9 @@ dependencies = [ [[package]] name = "jiff" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +checksum = "e67e8da4c49d6d9909fe03361f9b620f58898859f5c7aded68351e85e71ecf50" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -834,14 +834,14 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "jiff-static" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78" dependencies = [ "proc-macro2", "quote", @@ -1281,7 +1281,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1447,7 +1447,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1902,7 +1902,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index f5409ec7a..1bde504fb 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -21,8 +21,7 @@ path = "src/touch.rs" [dependencies] filetime = { workspace = true } clap = { workspace = true } -chrono = { workspace = true } -jiff = "0.2.15" +jiff = { workspace = true } parse_datetime = { workspace = true } thiserror = { workspace = true } uucore = { workspace = true, features = ["libc", "parser"] } diff --git a/src/uu/touch/src/error.rs b/src/uu/touch/src/error.rs index 8d23b7528..47823cde9 100644 --- a/src/uu/touch/src/error.rs +++ b/src/uu/touch/src/error.rs @@ -16,7 +16,7 @@ pub enum TouchError { #[error("{}", translate!("touch-error-unable-to-parse-date", "date" => .0.clone()))] InvalidDateFormat(String), - /// The source time couldn't be converted to a [`chrono::DateTime`] + /// The source time couldn't be converted to a [`jiff::Zoned`] #[error("{}", translate!("touch-error-invalid-filetime", "time" => .0))] InvalidFiletime(FileTime), diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index bde22ab33..3c1bab7a8 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -3,24 +3,24 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (ToDO) filetime datetime lpszfilepath mktime DATETIME datelike timelike UTIME +// spell-checker:ignore (ToDO) datelike datetime filetime lpszfilepath mktime strtime timelike utime // spell-checker:ignore (FORMATS) MMDDhhmm YYYYMMDDHHMM YYMMDDHHMM YYYYMMDDHHMMS pub mod error; -use chrono::{ - DateTime, Datelike, Duration, Local, LocalResult, NaiveDate, NaiveDateTime, NaiveTime, - TimeZone, Timelike, -}; use clap::builder::{PossibleValue, ValueParser}; use clap::{Arg, ArgAction, ArgGroup, ArgMatches, Command}; use filetime::{FileTime, set_file_times, set_symlink_file_times}; -use jiff::{Timestamp, Zoned}; +use jiff::civil::Time; +use jiff::fmt::strtime; +use jiff::tz::TimeZone; +use jiff::{Timestamp, ToSpan, Zoned}; use std::borrow::Cow; use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; use std::io::{Error, ErrorKind}; use std::path::{Path, PathBuf}; +use std::time::SystemTime; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; #[cfg(target_os = "linux")] @@ -125,16 +125,13 @@ mod format { pub(crate) const YYYYMMDDHHMM_OFFSET: &str = "%Y-%m-%d %H:%M %z"; } -/// Convert a [`DateTime`] with a TZ offset into a [`FileTime`] -/// -/// The [`DateTime`] is converted into a unix timestamp from which the [`FileTime`] is -/// constructed. -fn datetime_to_filetime(dt: &DateTime) -> FileTime { - FileTime::from_unix_time(dt.timestamp(), dt.timestamp_subsec_nanos()) +fn timestamp_to_filetime(ts: Timestamp) -> FileTime { + FileTime::from_system_time(SystemTime::from(ts)) } -fn filetime_to_datetime(ft: &FileTime) -> Option> { - Some(DateTime::from_timestamp(ft.unix_seconds(), ft.nanoseconds())?.into()) +fn filetime_to_zoned(ft: &FileTime) -> Option { + let ts = Timestamp::new(ft.unix_seconds(), ft.nanoseconds() as i32).ok()?; + Some(Zoned::new(ts, TimeZone::system())) } /// Whether all characters in the string are digits. @@ -385,12 +382,12 @@ pub fn touch(files: &[InputFile], opts: &Options) -> Result<(), TouchError> { if opts.date.is_none() { now = FileTime::from_unix_time(0, libc::UTIME_NOW as u32); } else { - now = datetime_to_filetime(&Local::now()); + now = timestamp_to_filetime(Timestamp::now()); } } #[cfg(not(target_os = "linux"))] { - now = datetime_to_filetime(&Local::now()); + now = timestamp_to_filetime(Timestamp::now()); } (now, now) } @@ -400,11 +397,11 @@ pub fn touch(files: &[InputFile], opts: &Options) -> Result<(), TouchError> { let (atime, mtime) = if let Some(date) = &opts.date { ( parse_date( - filetime_to_datetime(&atime).ok_or_else(|| TouchError::InvalidFiletime(atime))?, + filetime_to_zoned(&atime).ok_or_else(|| TouchError::InvalidFiletime(atime))?, date, )?, parse_date( - filetime_to_datetime(&mtime).ok_or_else(|| TouchError::InvalidFiletime(mtime))?, + filetime_to_zoned(&mtime).ok_or_else(|| TouchError::InvalidFiletime(mtime))?, date, )?, ) @@ -610,7 +607,7 @@ fn stat(path: &Path, follow: bool) -> std::io::Result<(FileTime, FileTime)> { )) } -fn parse_date(ref_time: DateTime, s: &str) -> Result { +fn parse_date(ref_zoned: Zoned, s: &str) -> Result { // This isn't actually compatible with GNU touch, but there doesn't seem to // be any simple specification for what format this parameter allows and I'm // not about to implement GNU parse_datetime. @@ -625,8 +622,11 @@ fn parse_date(ref_time: DateTime, s: &str) -> Result, s: &str) -> Result, s: &str) -> Result UResult { fn parse_timestamp(s: &str) -> UResult { use format::*; - let current_year = || Local::now().year(); + let current_year = || Timestamp::now().to_zoned(TimeZone::system()).year(); let (format, ts) = match s.chars().count() { 15 => (YYYYMMDDHHMM_DOT_SS, s.to_owned()), @@ -748,41 +722,37 @@ fn parse_timestamp(s: &str) -> UResult { } }; - let local = NaiveDateTime::parse_from_str(&ts, format).map_err(|_| { - USimpleError::new( - 1, - translate!("touch-error-invalid-date-ts-format", "date" => ts.quote()), - ) - })?; - let LocalResult::Single(mut local) = Local.from_local_datetime(&local) else { - return Err(USimpleError::new( - 1, - translate!("touch-error-invalid-date-ts-format", "date" => ts.quote()), - )); - }; + let mut dt = strtime::parse(format, &ts) + .and_then(|parsed| parsed.to_datetime()) + .map_err(|_| { + USimpleError::new( + 1, + translate!("touch-error-invalid-date-ts-format", "date" => ts.quote()), + ) + })?; - // Chrono caps seconds at 59, but 60 is valid. It might be a leap second + // Jiff caps seconds at 59, but 60 is valid. It might be a leap second // or wrap to the next minute. But that doesn't really matter, because we // only care about the timestamp anyway. // Tested in gnu/tests/touch/60-seconds - if local.second() == 59 && ts.ends_with(".60") { - local += Duration::try_seconds(1).unwrap(); + if dt.second() == 59 && ts.ends_with(".60") { + dt += 1.second(); } // Due to daylight saving time switch, local time can jump from 1:59 AM to - // 3:00 AM, in which case any time between 2:00 AM and 2:59 AM is not - // valid. If we are within this jump, chrono takes the offset from before - // the jump. If we then jump forward an hour, we get the new corrected - // offset. Jumping back will then now correctly take the jump into account. - let local2 = local + Duration::try_hours(1).unwrap() - Duration::try_hours(1).unwrap(); - if local.hour() != local2.hour() { - return Err(USimpleError::new( - 1, - translate!("touch-error-invalid-date-format", "date" => s.quote()), - )); - } + // 3:00 AM, in which case any time between 2:00 AM and 2:59 AM is not valid. + // Jiff's `to_ambiguous_zoned(...).unambiguous()` handles this case. + let local = TimeZone::system() + .to_ambiguous_zoned(dt) + .unambiguous() + .map_err(|_| { + USimpleError::new( + 1, + translate!("touch-error-invalid-date-ts-format", "date" => ts.quote()), + ) + })?; - Ok(datetime_to_filetime(&local)) + Ok(timestamp_to_filetime(local.timestamp())) } // TODO: this may be a good candidate to put in fsext.rs diff --git a/src/uu/uptime/Cargo.toml b/src/uu/uptime/Cargo.toml index e584fbb7d..651b342cd 100644 --- a/src/uu/uptime/Cargo.toml +++ b/src/uu/uptime/Cargo.toml @@ -23,11 +23,11 @@ feat_systemd_logind = ["uucore/feat_systemd_logind"] path = "src/uptime.rs" [dependencies] -chrono = { workspace = true } clap = { workspace = true } thiserror = { workspace = true } uucore = { workspace = true, features = ["libc", "utmpx", "uptime"] } fluent = { workspace = true } +jiff = { workspace = true } [target.'cfg(target_os = "openbsd")'.dependencies] utmp-classic = { workspace = true } diff --git a/src/uu/uptime/src/uptime.rs b/src/uu/uptime/src/uptime.rs index ca53d418a..89dc55d31 100644 --- a/src/uu/uptime/src/uptime.rs +++ b/src/uu/uptime/src/uptime.rs @@ -5,7 +5,8 @@ // spell-checker:ignore getloadavg behaviour loadavg uptime upsecs updays upmins uphours boottime nusers utmpxname gettime clockid couldnt -use chrono::{Local, TimeZone, Utc}; +use jiff::tz::TimeZone; +use jiff::{Timestamp, ToSpan}; #[cfg(unix)] use std::ffi::OsString; use std::io; @@ -196,10 +197,8 @@ fn uptime_since() -> UResult<()> { #[cfg(any(windows, target_os = "openbsd"))] let uptime = get_uptime(None)?; - let since_date = Local - .timestamp_opt(Utc::now().timestamp() - uptime, 0) - .unwrap(); - println!("{}", since_date.format("%Y-%m-%d %H:%M:%S")); + let since_date = (Timestamp::now() - uptime.seconds()).to_zoned(TimeZone::system()); + println!("{}", since_date.strftime("%Y-%m-%d %H:%M:%S")); Ok(()) } diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 0362dc097..d58d2ccca 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -23,7 +23,6 @@ path = "src/lib/lib.rs" [dependencies] bstr = { workspace = true, optional = true } -chrono = { workspace = true, optional = true } clap = { workspace = true } uucore_procs = { workspace = true } unit-prefix = { workspace = true, optional = true } @@ -185,5 +184,5 @@ version-cmp = [] wide = [] tty = [] time = ["jiff"] -uptime = ["chrono", "libc", "windows-sys", "utmpx", "utmp-classic"] +uptime = ["jiff", "libc", "windows-sys", "utmpx", "utmp-classic"] benchmark = ["divan", "tempfile"] diff --git a/src/uucore/src/lib/features/uptime.rs b/src/uucore/src/lib/features/uptime.rs index 91352f1de..10b073ad5 100644 --- a/src/uucore/src/lib/features/uptime.rs +++ b/src/uucore/src/lib/features/uptime.rs @@ -14,7 +14,8 @@ use crate::error::{UError, UResult}; use crate::translate; -use chrono::Local; +use jiff::Timestamp; +use jiff::tz::TimeZone; use libc::time_t; use thiserror::Error; @@ -38,7 +39,10 @@ impl UError for UptimeError { /// Returns the formatted time string, e.g. "12:34:56" pub fn get_formatted_time() -> String { - Local::now().time().format("%H:%M:%S").to_string() + Timestamp::now() + .to_zoned(TimeZone::system()) + .strftime("%H:%M:%S") + .to_string() } /// Safely get macOS boot time using sysctl command @@ -187,7 +191,7 @@ pub fn get_uptime(boot_time: Option) -> UResult { }; if let Some(t) = derived_boot_time { - let now = Local::now().timestamp(); + let now = Timestamp::now().as_second(); #[cfg(target_pointer_width = "64")] let boottime: i64 = t; #[cfg(not(target_pointer_width = "64"))] @@ -470,7 +474,7 @@ mod tests { assert!(boot_time > 946684800, "Boot time should be after year 2000"); // Boot time should be before current time - let now = chrono::Local::now().timestamp(); + let now = Timestamp::now().as_second(); assert!( (boot_time as i64) < now, "Boot time should be before current time" diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index b0613b146..97b3d1056 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -5,7 +5,10 @@ // // spell-checker: ignore: AEDT AEST EEST NZDT NZST Kolkata Iseconds -use chrono::{DateTime, Datelike, Duration, NaiveTime, Utc}; // spell-checker:disable-line +use std::cmp::Ordering; + +use jiff::tz::TimeZone; +use jiff::{Timestamp, ToSpan}; use regex::Regex; #[cfg(all(unix, not(target_os = "macos")))] use uucore::process::geteuid; @@ -485,7 +488,7 @@ fn test_invalid_format_string() { #[test] fn test_capitalized_numeric_time_zone() { // %z +hhmm numeric time zone (e.g., -0400) - // # is supposed to capitalize, which makes little sense here, but chrono crashes + // # is supposed to capitalize, which makes little sense here, but keep coverage // on such format so it's good to test. let re = Regex::new(r"^[+-]\d{4,4}\n$").unwrap(); new_ucmd!().arg("+%#z").succeeds().stdout_matches(&re); @@ -528,10 +531,10 @@ fn test_date_string_human() { #[test] fn test_negative_offset() { let data_formats = vec![ - ("-1 hour", Duration::hours(1)), - ("-1 hours", Duration::hours(1)), - ("-1 day", Duration::days(1)), - ("-2 weeks", Duration::weeks(2)), + ("-1 hour", 1.hours()), + ("-1 hours", 1.hours()), + ("-1 day", 24.hours()), + ("-2 weeks", (14 * 24).hours()), ]; for (date_format, offset) in data_formats { new_ucmd!() @@ -540,11 +543,10 @@ fn test_negative_offset() { .arg("--rfc-3339=seconds") .succeeds() .stdout_str_check(|out| { - let date = DateTime::parse_from_rfc3339(out.trim()).unwrap(); - + let date = out.trim().parse::().unwrap(); // Is the resulting date roughly what is expected? - let expected_date = Utc::now() - offset; - (date.to_utc() - expected_date).abs() < Duration::minutes(10) + let expected_date = Timestamp::now() - offset; + (date - expected_date).abs().compare(10.minutes()).unwrap() == Ordering::Less }); } } @@ -552,14 +554,15 @@ fn test_negative_offset() { #[test] fn test_relative_weekdays() { // Truncate time component to midnight - let today = Utc::now().with_time(NaiveTime::MIN).unwrap(); + let today = Timestamp::now().to_zoned(TimeZone::UTC).date(); // Loop through each day of the week, starting with today for offset in 0..7 { for direction in ["last", "this", "next"] { - let weekday = (today + Duration::days(offset)) - .weekday() - .to_string() - .to_lowercase(); + let weekday = today + .checked_add(offset.days()) + .unwrap() + .strftime("%a") + .to_string(); new_ucmd!() .arg("-d") .arg(format!("{direction} {weekday}")) @@ -567,14 +570,15 @@ fn test_relative_weekdays() { .arg("--utc") .succeeds() .stdout_str_check(|out| { - let result = DateTime::parse_from_rfc3339(out.trim()).unwrap().to_utc(); + let result = out.trim().parse::().unwrap(); let expected = match (direction, offset) { - ("last", _) => today - Duration::days(7 - offset), + ("last", _) => today.checked_sub((7 - offset).days()).unwrap(), ("this", 0) => today, - ("next", 0) => today + Duration::days(7), - _ => today + Duration::days(offset), + ("next", 0) => today.checked_add(7.days()).unwrap(), + _ => today.checked_add(offset.days()).unwrap(), }; - result == expected + let expected_ts = expected.to_zoned(TimeZone::UTC).unwrap().timestamp(); + result == expected_ts }); } } @@ -862,7 +866,7 @@ fn test_date_resolution_no_combine() { fn test_date_numeric_d_basic_utc() { // Verify GNU-compatible pure-digit parsing for -d STRING under UTC // 0/00 -> today at 00:00; 7/07 -> today at 07:00; 0700 -> today at 07:00 - let today = Utc::now().date_naive(); + let today = Timestamp::now().to_zoned(TimeZone::UTC).date(); let yyyy = today.year(); let mm = today.month(); let dd = today.day(); @@ -1134,9 +1138,7 @@ fn test_date_military_timezone_with_offset_variations() { #[test] fn test_date_military_timezone_with_offset_and_date() { - use chrono::{Duration, Utc}; - - let today = Utc::now().date_naive(); + let today = Timestamp::now().to_zoned(TimeZone::UTC).date(); let test_cases = vec![ ("m", -1), // M = UTC+12 @@ -1158,9 +1160,9 @@ fn test_date_military_timezone_with_offset_and_date() { ]; for (input, day_delta) in test_cases { - let expected_date = today.checked_add_signed(Duration::days(day_delta)).unwrap(); + let expected_date = today.checked_add(day_delta.days()).unwrap(); - let expected = format!("{}\n", expected_date.format("%F")); + let expected = format!("{}\n", expected_date.strftime("%F")); new_ucmd!() .env("TZ", "UTC") diff --git a/tests/by-util/test_pr.rs b/tests/by-util/test_pr.rs index d2e6cb675..2f02b5e0f 100644 --- a/tests/by-util/test_pr.rs +++ b/tests/by-util/test_pr.rs @@ -4,7 +4,7 @@ // file that was distributed with this source code. // spell-checker:ignore (ToDO) Sdivide -use chrono::{DateTime, Duration, Utc}; +use jiff::{Timestamp, ToSpan}; use regex::Regex; use std::fs::metadata; use uutests::new_ucmd; @@ -17,8 +17,8 @@ fn file_last_modified_time_format(ucmd: &UCommand, path: &str, format: &str) -> metadata(tmp_dir_path) .and_then(|meta| meta.modified()) .map(|mtime| { - let dt: DateTime = mtime.into(); - dt.format(format).to_string() + let dt: Timestamp = mtime.try_into().unwrap(); + dt.strftime(format).to_string() }) .unwrap_or_default() } @@ -27,19 +27,19 @@ fn file_last_modified_time(ucmd: &UCommand, path: &str) -> String { file_last_modified_time_format(ucmd, path, DATE_TIME_FORMAT_DEFAULT) } -fn all_minutes(from: DateTime, to: DateTime) -> Vec { - let to = to + Duration::try_minutes(1).unwrap(); +fn all_minutes(from: Timestamp, to: Timestamp) -> Vec { + let to = to + 1.minute(); let mut vec = vec![]; let mut current = from; while current < to { - vec.push(current.format(DATE_TIME_FORMAT_DEFAULT).to_string()); - current += Duration::try_minutes(1).unwrap(); + vec.push(current.strftime(DATE_TIME_FORMAT_DEFAULT).to_string()); + current += 1.minute(); } vec } -fn valid_last_modified_template_vars(from: DateTime) -> Vec> { - all_minutes(from, Utc::now()) +fn valid_last_modified_template_vars(from: Timestamp) -> Vec> { + all_minutes(from, Timestamp::now()) .into_iter() .map(|time| vec![("{last_modified_time}".to_string(), time)]) .collect() @@ -264,7 +264,7 @@ fn test_with_suppress_error_option() { fn test_with_stdin() { let expected_file_path = "stdin.log.expected"; let mut scenario = new_ucmd!(); - let start = Utc::now(); + let start = Timestamp::now(); scenario .pipe_in_fixture("stdin.log") .args(&["--pages=1:2", "-n", "-"]) @@ -327,7 +327,7 @@ fn test_with_mpr() { let expected_test_file_path = "mpr.log.expected"; let expected_test_file_path1 = "mpr1.log.expected"; let expected_test_file_path2 = "mpr2.log.expected"; - let start = Utc::now(); + let start = Timestamp::now(); new_ucmd!() .args(&["--pages=1:2", "-m", "-n", test_file_path, test_file_path1]) .succeeds() @@ -336,7 +336,7 @@ fn test_with_mpr() { &valid_last_modified_template_vars(start), ); - let start = Utc::now(); + let start = Timestamp::now(); new_ucmd!() .args(&["--pages=2:4", "-m", "-n", test_file_path, test_file_path1]) .succeeds() @@ -345,7 +345,7 @@ fn test_with_mpr() { &valid_last_modified_template_vars(start), ); - let start = Utc::now(); + let start = Timestamp::now(); new_ucmd!() .args(&[ "--pages=1:2", @@ -530,7 +530,7 @@ fn test_with_join_lines_option() { let test_file_2 = "test.log"; let expected_file_path = "joined.log.expected"; let mut scenario = new_ucmd!(); - let start = Utc::now(); + let start = Timestamp::now(); scenario .args(&["+1:2", "-J", "-m", test_file_1, test_file_2]) .succeeds()