Skip to content

Commit

Permalink
Merge pull request #4790 from sylvestre/date_use_humantime_to_duration
Browse files Browse the repository at this point in the history
date -d supports - 1 year ago, 2 second, etc
  • Loading branch information
sylvestre authored Apr 26, 2023
2 parents 360cbda + 825d240 commit 474d391
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions src/uu/date/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# spell-checker:ignore humantime
[package]
name = "uu_date"
version = "0.0.18"
Expand All @@ -16,8 +17,11 @@ path = "src/date.rs"

[dependencies]
chrono = { workspace=true }
#/ TODO: check if we can avoid chrono+time
time = { workspace=true }
clap = { workspace=true }
uucore = { workspace=true }
humantime_to_duration = { workspace=true }

[target.'cfg(unix)'.dependencies]
libc = { workspace=true }
Expand Down
21 changes: 18 additions & 3 deletions src/uu/date/src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (chrono) Datelike Timelike ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes
// spell-checker:ignore (chrono) Datelike Timelike ; (format) DATEFILE MMDDhhmm ; (vars) datetime datetimes humantime

use chrono::format::{Item, StrftimeItems};
use chrono::{DateTime, FixedOffset, Local, Offset, Utc};
use chrono::{DateTime, Duration as ChronoDuration, FixedOffset, Local, Offset, Utc};
#[cfg(windows)]
use chrono::{Datelike, Timelike};
use clap::{crate_version, Arg, ArgAction, Command};
Expand All @@ -18,6 +18,7 @@ use libc::{clock_settime, timespec, CLOCK_REALTIME};
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
use time::Duration;
use uucore::display::Quotable;
#[cfg(not(any(target_os = "redox")))]
use uucore::error::FromIo;
Expand Down Expand Up @@ -96,6 +97,7 @@ enum DateSource {
Now,
Custom(String),
File(PathBuf),
Human(Duration),
}

enum Iso8601Format {
Expand Down Expand Up @@ -168,7 +170,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
};

let date_source = if let Some(date) = matches.get_one::<String>(OPT_DATE) {
DateSource::Custom(date.into())
if let Ok(duration) = humantime_to_duration::from_str(date.as_str()) {
DateSource::Human(duration)
} else {
DateSource::Custom(date.into())
}
} else if let Some(file) = matches.get_one::<String>(OPT_FILE) {
DateSource::File(file.into())
} else {
Expand Down Expand Up @@ -219,6 +225,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let iter = std::iter::once(date);
Box::new(iter)
}
DateSource::Human(ref input) => {
// Get the current DateTime<FixedOffset> and convert the input time::Duration to chrono::Duration
// for things like "1 year ago"
let current_time = DateTime::<FixedOffset>::from(Local::now());
let input_chrono = ChronoDuration::seconds(input.as_seconds_f32() as i64)
+ ChronoDuration::nanoseconds(input.subsec_nanoseconds() as i64);
let iter = std::iter::once(Ok(current_time + input_chrono));
Box::new(iter)
}
DateSource::File(ref path) => {
if path.is_dir() {
return Err(USimpleError::new(
Expand Down
23 changes: 23 additions & 0 deletions tests/by-util/test_date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,29 @@ fn test_invalid_format_string() {
assert!(result.stderr_str().starts_with("date: invalid format "));
}

#[test]
fn test_date_string_human() {
let date_formats = vec![
"1 year ago",
"1 year",
"2 months ago",
"15 days ago",
"1 week ago",
"5 hours ago",
"30 minutes ago",
"10 seconds",
];
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!()
Expand Down

0 comments on commit 474d391

Please sign in to comment.