Add nanoseconds without dots

This commit is contained in:
Evan Schwartz 2018-06-08 14:37:03 -04:00
parent 0ef8c5cc83
commit 1de3658433
3 changed files with 48 additions and 2 deletions

View File

@ -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 =>

View File

@ -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!(":"),

View File

@ -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");