From f37b6c7cf5ee6a02251a2598e1451af568336bf0 Mon Sep 17 00:00:00 2001 From: Patrick Klitzke Date: Mon, 21 Aug 2023 11:30:38 +0900 Subject: [PATCH] date: Adds support datetime for parameter -d This resolved issue #5177. The PR adds a new enum HumanDuration(Duration), HumanDateTime(DateTime) and uses parse_datetime::parse_datetime::from_str to support datetime if relative time cannot be parsed. Furthermore tests are added for tests/by-util/test_date.rs. --- src/uu/date/src/date.rs | 13 ++++++++++--- tests/by-util/test_date.rs | 39 +++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/uu/date/src/date.rs b/src/uu/date/src/date.rs index 745fd54239c..afb056bdebb 100644 --- a/src/uu/date/src/date.rs +++ b/src/uu/date/src/date.rs @@ -92,7 +92,8 @@ enum DateSource { Now, Custom(String), File(PathBuf), - Human(Duration), + HumanDuration(Duration), + HumanDateTime(DateTime) } enum Iso8601Format { @@ -167,7 +168,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let date_source = if let Some(date) = matches.get_one::(OPT_DATE) { if let Ok(duration) = parse_datetime::from_str(date.as_str()) { - DateSource::Human(duration) + DateSource::HumanDuration(duration) + } else if let Ok(date_time) = parse_datetime::parse_datetime::from_str(date.as_str()) { + DateSource::HumanDateTime(date_time) } else { DateSource::Custom(date.into()) } @@ -221,7 +224,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let iter = std::iter::once(date); Box::new(iter) } - DateSource::Human(relative_time) => { + DateSource::HumanDuration(relative_time) => { // Get the current DateTime for things like "1 year ago" let current_time = DateTime::::from(Local::now()); // double check the result is overflow or not of the current_time + relative_time @@ -239,6 +242,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } } + DateSource::HumanDateTime(date) => { + let iter = std::iter::once(Ok(date)); + Box::new(iter) + } DateSource::File(ref path) => { if path.is_dir() { return Err(USimpleError::new( diff --git a/tests/by-util/test_date.rs b/tests/by-util/test_date.rs index a65f02fa4c7..4ce335cda1b 100644 --- a/tests/by-util/test_date.rs +++ b/tests/by-util/test_date.rs @@ -368,7 +368,7 @@ fn test_unsupported_format() { } #[test] -fn test_date_string_human() { +fn test_date_string_human_relative_time() { let date_formats = vec![ "1 year ago", "1 year", @@ -390,6 +390,43 @@ fn test_date_string_human() { } } +#[test] +fn test_date_string_human_date_time() { + let date_formats = vec![ + // unix timestamp format + "@0", + "@2", + "@10", + "@100", + "@2000", + "@1234400000", + "@1334400000", + "@1692582913", + "@2092582910", + // format YYYY-MM-DD + "2012-01-01", + "1999-01-12", + "2012-01-12", + // format YYYY-MM-DD HH:mm + "1970-01-01 00:00", + "2000-02-29 12:34", + "2100-02-28 23:59", + "2012-12-31 05:30", + "1800-01-01 18:45", + "9999-12-31 11:11", + "2023-08-21 14:55", // + ]; + let re = Regex::new(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}\n$").unwrap(); + for date_format in date_formats { + new_ucmd!() + .arg("-d") + .arg(date_format) + .arg("+%Y-%m-%d %S:%M") + .succeeds() + .stdout_matches(&re); + } +} + #[test] fn test_invalid_date_string() { new_ucmd!()