diff --git a/src/options/view.rs b/src/options/view.rs index caec38b4127572c63a6ad9f460c70965543671bc..2f1c7fa7b0689d7a3fa547f02bab7a1ed1662d5d 100644 --- a/src/options/view.rs +++ b/src/options/view.rs @@ -240,15 +240,16 @@ impl TimeFormat { /// Determine how time should be formatted in timestamp columns. fn deduce(matches: &getopts::Matches) -> Result { - pub use output::time::{DefaultFormat}; - const STYLES: &[&str] = &["default", "long-iso", "full-iso"]; + pub use output::time::{DefaultFormat, ISOFormat}; + const STYLES: &[&str] = &["default", "long-iso", "full-iso", "iso"]; if let Some(word) = matches.opt_str("time-style") { match &*word { "default" => Ok(TimeFormat::DefaultFormat(DefaultFormat::new())), + "iso" => Ok(TimeFormat::ISOFormat(ISOFormat::new())), "long-iso" => Ok(TimeFormat::LongISO), "full-iso" => Ok(TimeFormat::FullISO), - otherwise => Err(Misfire::bad_argument("time-style", otherwise, STYLES)) + otherwise => Err(Misfire::bad_argument("time-style", otherwise, STYLES)), } } else { diff --git a/src/output/time.rs b/src/output/time.rs index 49196398f13fb643702d96bd0cea13f038ce2cb4..5563020532d07f53905a9859a15ff00777e5129a 100644 --- a/src/output/time.rs +++ b/src/output/time.rs @@ -7,6 +7,7 @@ use fs::fields::Time; pub enum TimeFormat { DefaultFormat(DefaultFormat), + ISOFormat(ISOFormat), LongISO, FullISO, } @@ -15,6 +16,7 @@ impl TimeFormat { pub fn format_local(&self, time: Time) -> String { match *self { TimeFormat::DefaultFormat(ref fmt) => fmt.format_local(time), + TimeFormat::ISOFormat(ref iso) => iso.format_local(time), TimeFormat::LongISO => long_local(time), TimeFormat::FullISO => full_local(time), } @@ -23,6 +25,7 @@ impl TimeFormat { pub fn format_zoned(&self, time: Time, zone: &TimeZone) -> String { match *self { TimeFormat::DefaultFormat(ref fmt) => fmt.format_zoned(time, zone), + TimeFormat::ISOFormat(ref iso) => iso.format_zoned(time, zone), TimeFormat::LongISO => long_zoned(time, zone), TimeFormat::FullISO => full_zoned(time, zone), } @@ -141,3 +144,54 @@ fn full_zoned(time: Time, zone: &TimeZone) -> String { date.hour(), date.minute(), date.second(), time.nanoseconds, offset.hours(), offset.minutes().abs()) } + + + +#[derive(Debug, Clone)] +pub struct ISOFormat { + + /// The year of the current time. This gets used to determine which date + /// format to use. + pub current_year: i64, +} + +impl ISOFormat { + pub fn new() -> Self { + let current_year = LocalDateTime::now().year(); + ISOFormat { current_year } + } + + fn is_recent(&self, date: LocalDateTime) -> bool { + date.year() == self.current_year + } + + #[allow(trivial_numeric_casts)] + fn format_local(&self, time: Time) -> String { + let date = LocalDateTime::at(time.seconds as i64); + + if self.is_recent(date) { + format!("{:04}-{:02}-{:02}", + date.year(), date.month() as usize, date.day()) + } + else { + format!("{:02}-{:02} {:02}:{:02}", + date.month() as usize, date.day(), + date.hour(), date.minute()) + } + } + + #[allow(trivial_numeric_casts)] + fn format_zoned(&self, time: Time, zone: &TimeZone) -> String { + let date = zone.to_zoned(LocalDateTime::at(time.seconds as i64)); + + if self.is_recent(date) { + format!("{:04}-{:02}-{:02}", + date.year(), date.month() as usize, date.day()) + } + else { + format!("{:02}-{:02} {:02}:{:02}", + date.month() as usize, date.day(), + date.hour(), date.minute()) + } + } +} diff --git a/xtests/dates_iso b/xtests/dates_iso new file mode 100644 index 0000000000000000000000000000000000000000..276701955d7b0b892370e6f0fcd002d6795cc4c9 --- /dev/null +++ b/xtests/dates_iso @@ -0,0 +1,3 @@ +.rw-rw-r-- 0 cassowary 06-15 23:14 peach +.rw-rw-r-- 0 cassowary 03-03 00:00 pear +.rw-rw-r-- 0 cassowary 07-22 10:38 plum diff --git a/xtests/run.sh b/xtests/run.sh index da06d331964e7562d01241452d172ccfce83ac78..36046848d2cdbf248ca3fae606b80efe5083cb27 100755 --- a/xtests/run.sh +++ b/xtests/run.sh @@ -112,6 +112,7 @@ $exa $testcases/dates -lh --accessed --sort=accessed 2>&1 | diff -q - $results/d $exa $testcases/dates -lh --sort=modified 2>&1 | diff -q - $results/dates_modified || exit 1 $exa $testcases/dates -l --time-style=long-iso 2>&1 | diff -q - $results/dates_long_iso || exit 1 $exa $testcases/dates -l --time-style=full-iso 2>&1 | diff -q - $results/dates_full_iso || exit 1 +$exa $testcases/dates -l --time-style=iso 2>&1 | diff -q - $results/dates_iso || exit 1 # Paths and directories