From 7b316094180fcb5efb789fbf9e183d02f60c11d8 Mon Sep 17 00:00:00 2001 From: Tom Gallacher Date: Thu, 3 Sep 2015 13:40:34 +0100 Subject: [PATCH] Adding fixed precision for Nanosecond3, 6 and 9 --- src/format/mod.rs | 33 +++++++++++++++++++++++++++++++++ src/format/parse.rs | 21 +++++++++++++++++++++ src/format/strftime.rs | 15 +++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/src/format/mod.rs b/src/format/mod.rs index e20ecaf..939ad37 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -125,6 +125,12 @@ pub enum Fixed { /// May print nothing, 3, 6 or 9 digits according to the available accuracy. /// See also `Numeric::Nanosecond`. Nanosecond, + /// Fixed prescision at Nanosecond3 where 3 is the left aligned accuracy. + Nanosecond3, + /// Fixed prescision at Nanosecond6 where 6 is the left aligned accuracy. + Nanosecond6, + /// Fixed prescision at Nanosecond9 where 9 is the left aligned accuracy. + Nanosecond9, /// Timezone name. /// /// It does not support parsing, its use in the parser is an immediate failure. @@ -366,6 +372,33 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt write!(w, ".{:09}", nano) } }), + Nanosecond3 => + time.map(|t| { + let nano = t.nanosecond() % 1_000_000_000; + if nano == 0 { + write!(w, ".000") + } else { + write!(w, ".{:03}", nano / 1_000_000) + } + }), + Nanosecond6 => + time.map(|t| { + let nano = t.nanosecond() % 1_000_000_000; + if nano == 0 { + write!(w, ".000") + } else { + write!(w, ".{:06}", nano / 1_000) + } + }), + Nanosecond9 => + time.map(|t| { + let nano = t.nanosecond() % 1_000_000_000; + if nano == 0 { + write!(w, ".000") + } else { + 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 fbdda4e..fb135dd 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -307,6 +307,27 @@ pub fn parse<'a, I>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<( } } + Nanosecond3 => { + if s.starts_with(".") { + let nano = try_consume!(scan::nanosecond(&s[1..])); + try!(parsed.set_nanosecond(nano)); + } + } + + Nanosecond6 => { + if s.starts_with(".") { + let nano = try_consume!(scan::nanosecond(&s[1..])); + try!(parsed.set_nanosecond(nano)); + } + } + + Nanosecond9 => { + if s.starts_with(".") { + let nano = try_consume!(scan::nanosecond(&s[1..])); + try!(parsed.set_nanosecond(nano)); + } + } + TimezoneName => return Err(BAD_FORMAT), TimezoneOffsetColon | TimezoneOffset => { diff --git a/src/format/strftime.rs b/src/format/strftime.rs index 802a4cd..0efd8d6 100644 --- a/src/format/strftime.rs +++ b/src/format/strftime.rs @@ -254,6 +254,18 @@ impl<'a> Iterator for StrftimeItems<'a> { _ => Item::Error, }, '.' => match next!() { + '3' => match next!() { + 'f' => fix!(Nanosecond3), + _ => Item::Error, + }, + '6' => match next!() { + 'f' => fix!(Nanosecond6), + _ => Item::Error, + }, + '9' => match next!() { + 'f' => fix!(Nanosecond9), + _ => Item::Error, + }, 'f' => fix!(Nanosecond), _ => Item::Error, }, @@ -389,6 +401,9 @@ fn test_strftime_docs() { assert_eq!(dt.format("%S").to_string(), "60"); assert_eq!(dt.format("%f").to_string(), "026490000"); assert_eq!(dt.format("%.f").to_string(), ".026490"); + 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");