From 1de3658433c8d5b9a0167bfa20a10cd5e158c260 Mon Sep 17 00:00:00 2001 From: Evan Schwartz Date: Fri, 8 Jun 2018 14:37:03 -0400 Subject: [PATCH] Add nanoseconds without dots --- src/format/mod.rs | 23 ++++++++++++++++++++++- src/format/parse.rs | 12 +++++++++++- src/format/strftime.rs | 15 +++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/format/mod.rs b/src/format/mod.rs index caecb2b..32b5054 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -52,7 +52,7 @@ pub enum Pad { /// If the number is too long or (in some cases) negative, it is printed as is. /// /// The **parsing width** is the maximal width to be scanned. -/// The parser only tries to consume from one to given number of digits (greedily). +/// The parser only tries to consume from one to given number of digits (greedily). /// It also trims the preceding whitespaces if any. /// It cannot parse the negative number, so some date and time cannot be formatted then /// parsed with the same formatting items. @@ -177,6 +177,12 @@ pub enum Fixed { Nanosecond6, /// Same to [`Nanosecond`](#variant.Nanosecond) but the accuracy is fixed to 9. Nanosecond9, + /// Same to [`Nanosecond`](#variant.Nanosecond) but the accuracy is fixed to 3 and there is no leading dot. + Nanosecond3NoDot, + /// Same to [`Nanosecond`](#variant.Nanosecond) but the accuracy is fixed to 6 and there is no leading dot. + Nanosecond6NoDot, + /// Same to [`Nanosecond`](#variant.Nanosecond) but the accuracy is fixed to 9 and there is no leading dot. + Nanosecond9NoDot, /// Timezone name. /// /// It does not support parsing, its use in the parser is an immediate failure. @@ -475,6 +481,21 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt let nano = t.nanosecond() % 1_000_000_000; write!(w, ".{:09}", nano) }), + Nanosecond3NoDot => + time.map(|t| { + let nano = t.nanosecond() % 1_000_000_000; + write!(w, "{:03}", nano / 1_000_000) + }), + Nanosecond6NoDot => + time.map(|t| { + let nano = t.nanosecond() % 1_000_000_000; + write!(w, "{:06}", nano / 1_000) + }), + Nanosecond9NoDot => + time.map(|t| { + let nano = t.nanosecond() % 1_000_000_000; + write!(w, "{:09}", nano) + }), TimezoneName => off.map(|&(ref name, _)| write!(w, "{}", *name)), TimezoneOffsetColon => diff --git a/src/format/parse.rs b/src/format/parse.rs index c5b14a2..2892145 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -308,13 +308,18 @@ pub fn parse<'a, I>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<( s = &s[2..]; } - Nanosecond | Nanosecond3 | Nanosecond6 | Nanosecond9=> { + Nanosecond | Nanosecond3 | Nanosecond6 | Nanosecond9 => { if s.starts_with('.') { let nano = try_consume!(scan::nanosecond(&s[1..])); try!(parsed.set_nanosecond(nano)); } } + Nanosecond3NoDot | Nanosecond6NoDot | Nanosecond9NoDot => { + let nano = try_consume!(scan::nanosecond(&s[1..])); + try!(parsed.set_nanosecond(nano)); + } + TimezoneName => return Err(BAD_FORMAT), TimezoneOffsetColon | TimezoneOffset => { @@ -584,6 +589,11 @@ fn test_parse() { num!(Hour), lit!(":"), num!(Minute), lit!(":"), num!(Second), fix!(TimezoneOffset)]; year: 2015, month: 2, day: 4, hour_div_12: 1, hour_mod_12: 2, minute: 37, second: 5, offset: 32400); + check!("20150204143705567", + [num!(Year), num!(Month), num!(Day), + num!(Hour), num!(Minute), num!(Second), num!(Nanosecond)]; + year: 2015, month: 2, day: 4, hour_div_12: 1, hour_mod_12: 2, + minute: 37, second: 5, nanosecond: 567000000); check!("Mon, 10 Jun 2013 09:32:37 GMT", [fix!(ShortWeekdayName), lit!(","), sp!(" "), num!(Day), sp!(" "), fix!(ShortMonthName), sp!(" "), num!(Year), sp!(" "), num!(Hour), lit!(":"), diff --git a/src/format/strftime.rs b/src/format/strftime.rs index 3d65019..6226a17 100644 --- a/src/format/strftime.rs +++ b/src/format/strftime.rs @@ -295,6 +295,18 @@ impl<'a> Iterator for StrftimeItems<'a> { 'f' => fix!(Nanosecond), _ => Item::Error, }, + '3' => match next!() { + 'f' => fix!(Nanosecond3NoDot), + _ => Item::Error, + }, + '6' => match next!() { + 'f' => fix!(Nanosecond6NoDot), + _ => Item::Error, + }, + '9' => match next!() { + 'f' => fix!(Nanosecond9NoDot), + _ => Item::Error, + }, '%' => lit!("%"), _ => Item::Error, // no such specifier }; @@ -433,6 +445,9 @@ fn test_strftime_docs() { assert_eq!(dt.format("%.3f").to_string(), ".026"); assert_eq!(dt.format("%.6f").to_string(), ".026490"); assert_eq!(dt.format("%.9f").to_string(), ".026490000"); + assert_eq!(dt.format("%3f").to_string(), "026"); + assert_eq!(dt.format("%6f").to_string(), "026490"); + assert_eq!(dt.format("%9f").to_string(), "026490000"); assert_eq!(dt.format("%R").to_string(), "00:34"); assert_eq!(dt.format("%T").to_string(), "00:34:60"); assert_eq!(dt.format("%X").to_string(), "00:34:60");