From 1e4fc30f7be4a6002b0838d18d02b398560610e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 21 Nov 2025 06:15:08 +0100 Subject: [PATCH 1/2] relative: Support parsing floating relative values with spaces In case a string such as "now + 1.5 seconds" was parsed we were failing. This happened because after processing now, the parser was getting to the point in which the string contained "+ 1.5", and once the sign was processed, the remaining " 1.5" string conained a space that was causing sec_and_nsec to fail. Instead of failing at this point, just strip the spaces after the sign has been processed. Note in fact that "0+0.0 seconds" was working fine Closes: https://github.com/uutils/coreutils/issues/8618 --- src/items/relative.rs | 6 ++++-- src/lib.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/items/relative.rs b/src/items/relative.rs index 021f580..877d37b 100644 --- a/src/items/relative.rs +++ b/src/items/relative.rs @@ -83,7 +83,7 @@ pub(super) fn parse(input: &mut &str) -> ModalResult { fn seconds(input: &mut &str) -> ModalResult { ( opt(alt((s('+').value(1), s('-').value(-1)))), - sec_and_nsec, + s(sec_and_nsec), s(alpha1).verify(|s: &str| matches!(s, "seconds" | "second" | "sec" | "secs")), ago, ) @@ -138,11 +138,13 @@ mod tests { ("secs", Relative::Seconds(1, 0)), ("second ago", Relative::Seconds(-1, 0)), ("3 seconds", Relative::Seconds(3, 0)), + ("+ 3 seconds", Relative::Seconds(3, 0)), ("3.5 seconds", Relative::Seconds(3, 500_000_000)), ("-3.5 seconds", Relative::Seconds(-4, 500_000_000)), ("+3.5 seconds", Relative::Seconds(3, 500_000_000)), + ("+ 3.5 seconds", Relative::Seconds(3, 500_000_000)), ("3.5 seconds ago", Relative::Seconds(-4, 500_000_000)), - ("-3.5 seconds ago", Relative::Seconds(3, 500_000_000)), + ("- 3.5 seconds ago", Relative::Seconds(3, 500_000_000)), // Minutes ("minute", Relative::Minutes(1)), ("minutes", Relative::Minutes(1)), diff --git a/src/lib.rs b/src/lib.rs index 8e179ff..d24dbd9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -307,6 +307,42 @@ mod tests { assert!(parse_datetime(relative_time).is_ok()); } } + + #[test] + fn integer_seconds_offset() { + let dt = "0 + 0 seconds"; + assert!(parse_datetime(dt).is_ok()); + } + + #[test] + fn integer_seconds_offset_spaceless() { + let dt = "0+0 seconds"; + assert!(parse_datetime(dt).is_ok()); + } + + #[test] + fn floating_seconds_offset() { + let dt = "0 + 0.0 seconds"; + assert!(parse_datetime(dt).is_ok()); + } + + #[test] + fn floating_seconds_offset_spaceless() { + let dt = "0+0.0 seconds"; + assert!(parse_datetime(dt).is_ok()); + } + + #[test] + fn floating_seconds_offset_from_now() { + let dt = "now + 1.5 seconds"; + assert!(parse_datetime(dt).is_ok()); + } + + #[test] + fn floating_seconds_offset_from_tomorrow_spaceless() { + let dt = "tomorrow+1.5 seconds"; + assert!(parse_datetime(dt).is_ok()); + } } #[cfg(test)] From d6ab892c29ff9fd841cbce842bfdc04272bd037e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 21 Nov 2025 06:33:16 +0100 Subject: [PATCH 2/2] relative: Add more tests for parsing signed values with spaces --- src/items/relative.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/items/relative.rs b/src/items/relative.rs index 877d37b..5ed3888 100644 --- a/src/items/relative.rs +++ b/src/items/relative.rs @@ -152,29 +152,40 @@ mod tests { ("mins", Relative::Minutes(1)), ("10 minutes", Relative::Minutes(10)), ("-10 minutes", Relative::Minutes(-10)), + ("- 10 minutes", Relative::Minutes(-10)), ("10 minutes ago", Relative::Minutes(-10)), ("-10 minutes ago", Relative::Minutes(10)), + ("- 10 minutes ago", Relative::Minutes(10)), + ("-10 minutes ago", Relative::Minutes(10)), + ("- 10 minutes ago", Relative::Minutes(10)), // Hours ("hour", Relative::Hours(1)), ("hours", Relative::Hours(1)), ("10 hours", Relative::Hours(10)), ("+10 hours", Relative::Hours(10)), + ("+ 10 hours", Relative::Hours(10)), ("-10 hours", Relative::Hours(-10)), + ("- 10 hours", Relative::Hours(-10)), ("10 hours ago", Relative::Hours(-10)), ("-10 hours ago", Relative::Hours(10)), + ("- 10 hours ago", Relative::Hours(10)), // Days ("day", Relative::Days(1)), ("days", Relative::Days(1)), ("10 days", Relative::Days(10)), ("+10 days", Relative::Days(10)), + ("+ 10 days", Relative::Days(10)), ("-10 days", Relative::Days(-10)), + ("- 10 days", Relative::Days(-10)), ("10 days ago", Relative::Days(-10)), ("-10 days ago", Relative::Days(10)), + ("- 10 days ago", Relative::Days(10)), // Multiple days ("fortnight", Relative::Days(14)), ("fortnights", Relative::Days(14)), ("2 fortnights ago", Relative::Days(-28)), ("+2 fortnights ago", Relative::Days(-28)), + ("+ 2 fortnights ago", Relative::Days(-28)), ("week", Relative::Days(7)), ("weeks", Relative::Days(7)), ("2 weeks ago", Relative::Days(-14)),