Add long-iso style and --time-style option

This has to do its own number formatting because *somebody* didn’t add “print the current month number” functionality to rust-datetime!
This commit is contained in:
Benjamin Sago 2017-07-06 00:01:45 +01:00
parent 98b63705be
commit 786e8f4d7f
5 changed files with 54 additions and 18 deletions

View File

@ -77,17 +77,18 @@ impl Options {
opts.optopt ("I", "ignore-glob", "ignore files that match these glob patterns", "GLOB1|GLOB2...");
// Long view options
opts.optflag("b", "binary", "list file sizes with binary prefixes");
opts.optflag("B", "bytes", "list file sizes in bytes, without prefixes");
opts.optflag("g", "group", "list each file's group");
opts.optflag("h", "header", "add a header row to each column");
opts.optflag("H", "links", "list each file's number of hard links");
opts.optflag("i", "inode", "list each file's inode number");
opts.optflag("m", "modified", "use the modified timestamp field");
opts.optflag("S", "blocks", "list each file's number of file system blocks");
opts.optopt ("t", "time", "which timestamp field to show", "WORD");
opts.optflag("u", "accessed", "use the accessed timestamp field");
opts.optflag("U", "created", "use the created timestamp field");
opts.optflag("b", "binary", "list file sizes with binary prefixes");
opts.optflag("B", "bytes", "list file sizes in bytes, without prefixes");
opts.optflag("g", "group", "list each file's group");
opts.optflag("h", "header", "add a header row to each column");
opts.optflag("H", "links", "list each file's number of hard links");
opts.optflag("i", "inode", "list each file's inode number");
opts.optflag("m", "modified", "use the modified timestamp field");
opts.optflag("S", "blocks", "list each file's number of file system blocks");
opts.optopt ("t", "time", "which timestamp field to show", "WORD");
opts.optflag("u", "accessed", "use the accessed timestamp field");
opts.optflag("U", "created", "use the created timestamp field");
opts.optopt ("", "time-style", "how to format timestamp fields", "STYLE");
if cfg!(feature="git") {
opts.optflag("", "git", "list each file's git status");

View File

@ -6,7 +6,7 @@ use output::Colours;
use output::{grid, details};
use output::table::{TimeTypes, Environment, SizeFormat, Options as TableOptions};
use output::file_name::Classify;
use output::time::{TimeFormat, DefaultFormat};
use output::time::TimeFormat;
use options::Misfire;
use fs::feature::xattr;
@ -239,8 +239,20 @@ impl SizeFormat {
impl TimeFormat {
/// Determine how time should be formatted in timestamp columns.
fn deduce(_matches: &getopts::Matches) -> Result<TimeFormat, Misfire> {
Ok(TimeFormat::DefaultFormat(DefaultFormat::new()))
fn deduce(matches: &getopts::Matches) -> Result<TimeFormat, Misfire> {
pub use output::time::{DefaultFormat, LongISO};
const STYLES: &[&str] = &["default", "long-iso"];
if let Some(word) = matches.opt_str("time-style") {
match &*word {
"default" => Ok(TimeFormat::DefaultFormat(DefaultFormat::new())),
"long-iso" => Ok(TimeFormat::LongISO(LongISO)),
otherwise => Err(Misfire::bad_argument("time-style", otherwise, STYLES))
}
}
else {
Ok(TimeFormat::DefaultFormat(DefaultFormat::new()))
}
}
}

View File

@ -1,4 +1,4 @@
use datetime::{LocalDateTime, TimeZone, DatePiece};
use datetime::{LocalDateTime, TimeZone, DatePiece, TimePiece};
use datetime::fmt::DateFormat;
use locale;
@ -7,18 +7,21 @@ use fs::fields::Time;
pub enum TimeFormat {
DefaultFormat(DefaultFormat),
LongISO(LongISO),
}
impl TimeFormat {
pub fn format_local(&self, time: Time) -> String {
match *self {
TimeFormat::DefaultFormat(ref fmt) => fmt.format_local(time),
TimeFormat::LongISO(ref iso) => iso.format_local(time),
}
}
pub fn format_zoned(&self, time: Time, zone: &TimeZone) -> String {
match *self {
TimeFormat::DefaultFormat(ref fmt) => fmt.format_zoned(time, zone),
TimeFormat::LongISO(ref iso) => iso.format_zoned(time, zone),
}
}
}
@ -71,9 +74,6 @@ impl DefaultFormat {
fn is_recent(&self, date: LocalDateTime) -> bool {
date.year() == self.current_year
}
}
impl DefaultFormat {
#[allow(trivial_numeric_casts)]
fn format_local(&self, time: Time) -> String {
@ -99,3 +99,22 @@ impl DefaultFormat {
}
}
}
pub struct LongISO;
impl LongISO {
#[allow(trivial_numeric_casts)]
fn format_local(&self, time: Time) -> String {
let date = LocalDateTime::at(time.seconds as i64);
format!("{:04}-{:02}-{:02} {:02}:{:02}",
date.year(), 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));
format!("{:04}-{:02}-{:02} {:02}:{:02}",
date.year(), date.month() as usize, date.day(), date.hour(), date.minute())
}
}

3
xtests/dates_long_iso Normal file
View File

@ -0,0 +1,3 @@
.rw-rw-r-- 0 cassowary 2006-06-15 23:14 peach
.rw-rw-r-- 0 cassowary 2003-03-03 00:00 pear
.rw-rw-r-- 0 cassowary 2009-07-22 10:38 plum

View File

@ -110,6 +110,7 @@ $exa $testcases/file-names-exts/music.* -I "*.OGG|*.mp3" -1 2>&1 | diff -q - $re
# Dates and times
$exa $testcases/dates -lh --accessed --sort=accessed 2>&1 | diff -q - $results/dates_accessed || exit 1
$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
# Paths and directories